Part 0 - Topic introduction
People always use a lot of personal pronouns to avoid repeating someone’s names time and time again. Different people may use different personal pronouns for different weight in different situation to demonstrate different meanings and emotions. What about the situations in presidents’ Inaugural Speeches?
Part 1 - Packages preparaion
packages.used=c("RColorBrewer","qdap","ggplot2","reshape2","syuzhet","tm","qdap","reshape2","gridExtra","ggplot2","wordcloud","dplyr","tidytext")
# check packages that need to be installed.
packages.needed=setdiff(packages.used,
intersect(installed.packages()[,1],
packages.used))
# install additional packages
if(length(packages.needed)>0){
install.packages(packages.needed, dependencies = TRUE)
}
require(devtools,quietly = T)
install_github('recharts', 'taiyun')
# library packages
library("RColorBrewer",quietly = T)
library("qdap",quietly = T)
library("ggplot2",quietly = T)
library("reshape2",quietly = T)
library("syuzhet",quietly = T)
library("tm",quietly = T)
library("qdap",quietly = T)
library("reshape2",quietly = T)
library("gridExtra",quietly = T)
library("ggplot2",quietly = T)
library("wordcloud",quietly = T)
library("dplyr",quietly = T)
library("tidytext",quietly = T)
library("recharts",quietly = T)
#part of codes are in this R file.
source("../lib/customized_function.R")
Part 2 - Data cleaning
We count the word frequency for each speeches and make this data matrix on which our whole analysis would based.
inaug.list=read.csv("../data/InaugurationInfo.csv", stringsAsFactors = FALSE)
inaug.data=read.table("../data/InauguationDates.txt", stringsAsFactors = FALSE,blank.lines.skip=F,sep= "\t")
mat1<-NULL
for(i in seq(nrow(inaug.list))) {
filename <- paste0("../data/InauguralSpeeches/inaug",
inaug.list$File[i], "-",
inaug.list$Term[i], ".txt")
tx <- readLines(filename,warn=F)
if (i==58)
{
tx<-paste(tx, collapse = " ")
tx_words <- strsplit(tx, split = " ")[[1]]
}
else
tx_words <- strsplit(tx, split = " ")[[1]]
date_pattern2 <- "[a-zA-z]+"
tx_words2 <- grep(tx_words, pattern = date_pattern2, value=T)
tx_log <- grepl(tx_words2, pattern = date_pattern2)
matches <- gregexpr(pattern = date_pattern2, text = tx_words2[tx_log])
tx_words <- unlist(regmatches(tx_words2[tx_log], matches))
tx_words <- unlist(rm_stopwords(tx_words))
mat<-NULL
table<-table(tx_words)
word<-names(table)
n<-unname(table)
matname<-paste(inaug.list$File[i],inaug.list$Term[i])
mat<-cbind(rep(matname,nrow(n)),word,n)
mat1<-rbind(mat1,mat)
}
colnames(mat1)<-c("name","word","n")
matsort<-mat1[order(as.numeric(mat1[,3]),decreasing = T),]
head(matsort)
name word n
[1,] "WilliamHenryHarrison 1" "which" "107"
[2,] "WilliamHenryHarrison 1" "by" "103"
[3,] "JamesKPolk 1" "our" "101"
[4,] "CalvinCoolidge 1" "we" "88"
[5,] "WilliamHenryHarrison 1" "their" "81"
[6,] "WarrenGHarding 1" "we" "80"
Part 3 - Different president uses personal pronoun for different weight
In this part,we will do a general analysis,to see the general trend and find difference of the weight when divided by different factors.By saying weight,we mean the times one using a certain personal pronoun divided by the total times he using all four types of pronouns.
We divide personal pronouns into 4 types,first person singular form,first person plural form,second person form and third person form.
#personal pronoun
first1<-c("I","me","mine","my")
first2<-c("we","our","ours","us")
second<-c("you","your","yours")
third<-c("he","she","it","him","her","his","hers","they","them","their")
personal<-list(first1,first2,second,third)
pp_mat<-matrix(nrow = nrow(inaug.list),ncol = 4)
for(i in seq(nrow(inaug.list))) {
test<-matsort[matsort[,"name"]==paste(inaug.list$File[i],inaug.list$Term[i]),"word"]
pp_mat[i,]<-find_personal_pronoun(test)
}
ppname<-NULL
for(i in seq(nrow(inaug.list))) {
ppname[i] <- paste(inaug.list$File[i], inaug.list$Term[i]) }
rownames(pp_mat)<-ppname
colnames(pp_mat)<-c("first1","first2","second","third")
head(pp_mat)
first1 first2 second third
GeorgeWashington 1 0.2222222 0.3333333 0.1111111 0.3333333
GeorgeWashington 2 0.6666667 0.0000000 0.3333333 0.0000000
JohnAdams 1 0.2222222 0.4444444 0.1111111 0.2222222
ThomasJefferson 1 0.2222222 0.3333333 0.1111111 0.3333333
ThomasJefferson 2 0.2500000 0.3750000 0.1250000 0.2500000
JamesMadison 1 0.2857143 0.4285714 0.0000000 0.2857143
pp_mat1<-pp_mat
rownames(pp_mat1)<-seq(1789,2017,4)
pp_mat2<-melt(pp_mat1)
pp_mat3<-melt(pp_mat)
new1<-mat2mat(pp_mat)
a<-ggplot(data.frame(personal_pronoun=new1[,"type"],new1[,"name"],new1[,"prop"]), aes(x=factor(new1[,"name"], levels=unique(new1[,"name"])),y=new1[,"prop"], colour=personal_pronoun,group=personal_pronoun))+ geom_line(size=2) + theme(axis.text.x = element_blank()) + xlab("time with different presidents") + ylab("proportion")
pp_dat<-data.frame(year=pp_mat2$Var1,proportion=pp_mat2$value,personal_pronoun=pp_mat2$Var2)
b<-ggplot(pp_dat, aes(x = year, y = proportion, fill = personal_pronoun)) +
geom_area() +
scale_fill_brewer(palette = "Blues", breaks = rev(c("third","second","first2","first1")))
pp_dat<-data.frame(president=pp_mat3$Var1,proportion=pp_mat2$value,personal_pronoun=pp_mat2$Var2)
c<-ggplot(pp_dat,aes(president,proportion,fill=personal_pronoun))+geom_bar(stat="identity",position="stack")+ggtitle("")+guides(fill=guide_legend(title=NULL))+
scale_fill_brewer(palette = "Blues")+ theme(axis.text.x = element_blank()) + xlab("time with different presidents")
#grid.arrange(b,c,nrow=2)
Notice:The plot(and some following plots) are interactive by moving your mouse to a certain data point,details can be shown.
3.1 General Trend
x-axis:time (different presidents) y-axis:the weight of a certain kind of personal pronoun being used.
eArea(pp_mat1)
In general
- There is no obvious trend,just some fluctuations for second & third person using weight.
- There is a slightly decreasing for first person singular form using weight.
- There is a slightly increasing for first person plural form using weight.
It’s quite reasonable,since presidents come to realize that they should emphasize people’s rights and responsibilities to let people feel that they are being together,the interests of every citizens are closely related to destiny of the United States,rather than just talking about themselves.
3.2 Comparing between different terms
#different term
avg<-apply(pp_mat,2,mean)
list<-term_sep()
avg_term1<-apply(pp_mat[list[[1]],],2,mean)
avg_term2<-apply(pp_mat[list[[2]],],2,mean)
df1<-data.frame(avg,avg_term1,avg_term2)
dat<-t(df1)
mydat<-melt(dat)
#mydat
mydat<-data.frame(term = mydat$Var1,personal_pronoun = mydat$Var2,proportion=round(mydat$value,2))
ggplot(mydat,aes(term,proportion,fill=personal_pronoun))+geom_bar(stat="identity",position="stack")+ggtitle("")+theme(axis.ticks.length=unit(0.5,'cm'))+guides(fill=guide_legend(title=NULL))+
scale_fill_brewer(palette = "Blues")

eRadar(xtabs( proportion~ term+personal_pronoun, mydat))
From president’s term 1 to term 2,they tend to use more first person plural form than first person singular form.It’s also reasonable, since the president and the public become familiar to each other,so the president naturally take himself and the public as a whole group.
3.3 Comparing among different parties
#different party
new_inaug.list<-cbind(inaug.list,pp_mat)
first1<-tapply(new_inaug.list$first1,new_inaug.list$Party,mean)
first2<-tapply(new_inaug.list$first2,new_inaug.list$Party,mean)
second<-tapply(new_inaug.list$second,new_inaug.list$Party,mean)
third<-tapply(new_inaug.list$third,new_inaug.list$Party,mean)
#head(new_inaug.list)
#aggregate(new_inaug.list,)
dat<-rbind(unname(first1),unname(first2),unname(second),unname(third))
colnames(dat)<-names(first1)
rownames(dat)<-c("first1","first2","second","third")
mydat<-melt(dat)
mydat<-data.frame(personal_pronoun = mydat$Var1, party = mydat$Var2,proportion=round(mydat$value,2))
ggplot(mydat,aes(party,proportion,fill=personal_pronoun))+geom_bar(stat="identity",position="stack")+ggtitle("")+theme(axis.ticks.length=unit(0.5,'cm'))+guides(fill=guide_legend(title=NULL))+
scale_fill_brewer(palette = "Blues")+ theme(axis.text.x = element_text(angle = 15, hjust = 0.5, vjust = 0.5))

eRadar(xtabs( proportion~ party+personal_pronoun, mydat))
As the plot shown,Whig used first person singular form and third person most frequently,used first person plural form as well as second person at least frequency.While federalist is almost the opposite.
Part 4 - Analysis on each kind of personal pronoun’s CRAZY FAN
In this part, we switch our analysis from the overall data to some extreme points, to analysis the features about those presidents who use a certain type of personal pronoun at a high frequency,like top 10.
data1<-pp_mat[order(pp_mat[,1],decreasing = T),][1:10,]
data2<-pp_mat[order(pp_mat[,2],decreasing = T),][1:10,]
data3<-pp_mat[order(pp_mat[,3],decreasing = T),][1:10,]
data4<-pp_mat[order(pp_mat[,4],decreasing = T),][1:10,]
new1<-mat2mat(data1)
new2<-mat2mat(data2)
new3<-mat2mat(data3)
new4<-mat2mat(data4)
new1<-data.frame(type=new1[,"type"],name=new1[,"name"],proportion=as.numeric(new1[,"prop"]))
new2<-data.frame(type=new2[,"type"],name=new2[,"name"],proportion=as.numeric(new2[,"prop"]))
new3<-data.frame(type=new3[,"type"],name=new3[,"name"],proportion=as.numeric(new3[,"prop"]))
new4<-data.frame(type=new4[,"type"],name=new4[,"name"],proportion=as.numeric(new4[,"prop"]))
inaug.list=read.csv("../data/InaugurationInfo.csv", stringsAsFactors = FALSE)
inaug.data=read.table("../data/InauguationDates.txt", stringsAsFactors = FALSE,blank.lines.skip=F,sep= "\t")
first1<-c("I","me","mine","my")
first2<-c("we","our","ours","us")
second<-c("you","your","yours")
third<-c("he","she","it","him","her","his","hers","they","them","their")
personal<-list(first1,first2,second,third)
speech.list=read.csv("../data/InaugurationInfo.csv", stringsAsFactors = FALSE)
speech.list$type=c(rep("inaug", nrow(speech.list)))
speech.list$fulltext=NA
sentence.list=NULL
4.1 Top ten using first person singular form
- x-axis:different presidents
- y-axis:the weight of a certain kind of personal pronoun being used.
eBar(new1, ~name, ~proportion, ~type)
test<-topic_wc(2,1)
dat<-data.frame(word=test[,"word"],freq=5*as.numeric(test[,"n"]))
#par(mfrow=c(1,2))
eWordcloud(dat[7:65,], namevar = ~word, datavar = ~freq,size = c(600, 600),title = "George Washington & first person singular",rotationRange = c(-1, 1))
test<-topic_wc(2,3)
dat<-data.frame(word=test[,"word"],freq=5*as.numeric(test[,"n"]))
eWordcloud(dat[2:32,], namevar = ~word, datavar = ~freq,size = c(600, 600),title = "George Washington & second person",rotationRange = c(-1, 1))
No.1 “first person singular user” is George Washington(term 2).The 67% personal pronoun George Washington used in his second person is first person singular form. He also used second person quite frequently at about 33%. Along with the word cloud,we can speculate in his speeches,no matter using first singular form or second form,he used words like “administration”,“chief”,it was shown that he took himself as a leader and wanted to express his power to public.
test<-matsort[matsort[,"name"] == "WilliamMcKinley 1",]
test1<-matsort[matsort[,"name"] == "WoodrowWilson 2",]
test2<-matsort[matsort[,"name"] == "JamesBuchanan 1",]
test<-rbind(test,test1,test2)
test<-test[order(as.numeric(test[,3]),decreasing = T),]
test<-test[17:2529,]
dat<-data.frame(word=test[,"word"],freq=test[,"n"])
#par(mfrow=c(1,2))
eWordcloud(dat, namevar = ~word, datavar = ~freq,size = c(600, 600),title = "WilliamMcKinley 1 & WoodrowWilson 2 & JamesBuchanan 1",rotationRange = c(-1, 1))
Except Washington,from No.2 William McKinley(term 1) to No.4 James Buchanan(term 1),they didn’t even use second person.Add their three’s speeches to make the wordcloud,we can hardly find the words demonstrating centralization of power, instead,there are words like “congress”,“fair”,“civil”,“life”,showing more gentle emotion.
4.2 Top ten using first person plural form
- x-axis:different presidents
- y-axis:the weight of a certain kind of personal pronoun being used.
eBar(new2, ~name, ~proportion, ~type)
test<-matsort[matsort[,"name"] == "FranklinDRoosevelt 3",]
test1<-matsort[matsort[,"name"] == "TheodoreRoosevelt 1",]
test2<-matsort[matsort[,"name"] == "AndrewJackson 1",]
test3<-matsort[matsort[,"name"] == "AbrahamLincoln 2",]
test4<-matsort[matsort[,"name"] == "WilliamMcKinley 2",]
test5<-matsort[matsort[,"name"] == "FranklinDRoosevelt 4",]
test<-rbind(test,test1,test2,test3,test4,test5)
test<-test[order(as.numeric(test[,3]),decreasing = T),]
test<-test[40:2638,]
dat<-data.frame(word=test[,"word"],freq=test[,"n"])
#par(mfrow=c(1,2))
eWordcloud(dat, namevar = ~word, datavar = ~freq,size = c(600, 600),title = "TOP 6 using first person plural form",rotationRange = c(-1, 1))
For presidents frequently using first person plural form, there exists similar phenomenon.From No.1 Franklin DRoosevelt(term 3) to No.6 Franklin DRoosevelt(term 4),they also make the speeches without using second person.Add their speeches to make the wordcloud,we find similar words showing gentle emotion.
4.3 Top ten using second person
- x-axis:different presidents
- y-axis:the weight of a certain kind of personal pronoun being used.
eBar(new3, ~name, ~proportion, ~type)
4.4 Top ten using third person
- x-axis:different presidents
- y-axis:the weight of a certain kind of personal pronoun being used.
eBar(new4, ~name, ~proportion, ~type)
4.5 Each personal pronoun’s “Fan Club” feature : positive? negative?
data(positive.words)
data(negative.words)
sentiment_analy<-function(words)
{
score<-NULL
# compare words to the dictionaries of positive & negative terms
positive.matches = match(words, positive.words)
negative.matches = match(words, negative.words)
# get the position of the matched term or NA
# we just want a TRUE/FALSE
positive_matches = !is.na(positive.matches)
negative_matches = !is.na(negative.matches)
score = sum(positive_matches) - sum(negative_matches)
return(score)
}
senti_vec<-NULL
for(i in seq(nrow(inaug.list))) {
test<-matsort[matsort[,"name"]==paste(inaug.list$File[i],inaug.list$Term[i]),"word"]
senti_vec[i]<-sentiment_analy(test)
}
svname<-NULL
for(i in seq(nrow(inaug.list))) {
svname[i] <- paste(inaug.list$File[i], inaug.list$Term[i]) }
#sentiment vs person
senti_mat<-cbind(ppname,senti_vec)
n1<-match(rownames(data1),ppname)
n2<-match(rownames(data2),ppname)
n3<-match(rownames(data3),ppname)
n4<-match(rownames(data4),ppname)
senti_mat2<-cbind(senti_mat[n1,2],rep("first1",10))
senti_mat2<-rbind( senti_mat2 , cbind(senti_mat[n2,2],rep("first2",10)) )
senti_mat2<-rbind( senti_mat2 , cbind(senti_mat[n3,2],rep("second",10)) )
senti_mat2<-rbind( senti_mat2 , cbind(senti_mat[n4,2],rep("third",10)) )
colnames(senti_mat2)<-c("sentimental_scores","personal_pron")
dat<-data.frame(senti_mat2)
p <- ggplot(dat, aes(personal_pron, as.numeric(sentimental_scores)))
p + geom_boxplot()

According to the plot, First person plural’s “Fan Club” tend to be more negative,while the third person form’s “Fan Club” seem to be more positive. But there is no obvious differences.
4.6 Each personal pronoun’s “Fan Club” feature : average of word using times?
#avg time vs person
avg_mat<-matrix(nrow = nrow(inaug.list),ncol = 2)
avg_mat[,1]<-ppname
for(i in seq(nrow(inaug.list))) {
test<-matsort[matsort[,"name"]==paste(inaug.list$File[i],inaug.list$Term[i]),]
avg_mat[i,2]<-sum(as.numeric(test[,3]))/nrow(test)
}
senti_mat3<-cbind(avg_mat[n1,2],rep("first1",10))
senti_mat3<-rbind( senti_mat3 , cbind(avg_mat[n2,2],rep("first2",10)) )
senti_mat3<-rbind( senti_mat3 , cbind(avg_mat[n3,2],rep("second",10)) )
senti_mat3<-rbind( senti_mat3 , cbind(avg_mat[n4,2],rep("third",10)) )
colnames(senti_mat3)<-c("word_avg_time","personal_pron")
dat<-data.frame(senti_mat3)
p <- ggplot(dat, aes(personal_pron, as.numeric(word_avg_time)))
p + geom_boxplot()

According to the plot, First person plural’s “Fan Club” tend to use the same words for less times,the median is about 12 times;while the third person form’s “Fan Club” using the same words for more times,the median is about 27 times.
Part 5 - What are they talking/feeling using personal pronoun ?
In this part,we go a little deeper to each sentences.What’s the weight of personal pronouns used in each sentences? In those sentences,what are they talking about and what emotion are they try to convey,these are what we care in this part.
We mainly make two plots to compare.One of them is stacked bar plot,demonstrating the four proportions of four personal pronouns for each sentence in one speech.The second is an area plot,showing different emotions for each sentence in one speech.
After check the plots for each presidents one by one,I will share three findings here.
Finding 1:first singular form always come with trust and anticipation.
- George Washington: There are 4 sentences in his speeches,with 1,2 and 4 using high frequency of first person singular pronoun,and the emotions of these sentences are mainly trust.
senten_mat2<-melt(senten_mat(2))
sen_dat<-data.frame(sentence.number=senten_mat2$Var1,times=senten_mat2$value,personal_pronoun=senten_mat2$Var2,2)
senti_mat<-round(count_emo(2)[,c(1,2,4,5,7,8)],2)
rownames(senti_mat)<-seq(1,nrow(senti_mat))
senti_mat2<-melt(senti_mat)
senti_dat<-data.frame(sentence_number=senti_mat2$Var1,score=senti_mat2$value,sentiment=senti_mat2$Var2)
#par(mfrow=c(1,2))
a1<-ggplot(sen_dat,aes(sentence.number,times,fill=personal_pronoun))+geom_bar(stat="identity",position="stack")+ggtitle("")+guides(fill=guide_legend(title=NULL))+ scale_fill_brewer(palette = "Blues")+ xlab("sentence number")
#b1<-ggplot(senti_dat, aes(x = sentence_number, y = score, fill = sentiment)) +
# geom_area()
# + scale_fill_brewer(palette = "RdBu", breaks = rev(c(factor(sentiment))))
#b1<-ggplot(senti_dat,aes(x = sentence_number, y = score, fill = sentiment))+geom_bar(stat="identity",position="stack")+ggtitle("")+guides(fill=guide_legend(title=NULL))
#grid.arrange(a1,b1,nrow=2)
a1
senten_mat2<-melt(senten_mat(2))
sen_dat<-data.frame(sentence.number=senten_mat2$Var1,times=senten_mat2$value,personal_pronoun=senten_mat2$Var2,2)
senti_mat<-round(count_emo(2)[,c(1,2,4,5,7,8)],2)
rownames(senti_mat)<-seq(1,nrow(senti_mat))
senti_mat2<-melt(senti_mat)
senti_dat<-data.frame(sentence_number=senti_mat2$Var1,score=senti_mat2$value,sentiment=senti_mat2$Var2)
#par(mfrow=c(1,2))
a1<-ggplot(sen_dat,aes(sentence.number,times,fill=personal_pronoun))+geom_bar(stat="identity",position="stack")+ggtitle("")+guides(fill=guide_legend(title=NULL))+ scale_fill_brewer(palette = "Blues")+ xlab("sentence number")
#b1<-ggplot(senti_dat, aes(x = sentence_number, y = score, fill = sentiment)) +
# geom_area()
# + scale_fill_brewer(palette = "RdBu", breaks = rev(c(factor(sentiment))))
#b1<-ggplot(senti_dat,aes(x = sentence_number, y = score, fill = sentiment))+geom_bar(stat="identity",position="stack")+ggtitle("")+guides(fill=guide_legend(title=NULL))
#grid.arrange(a1,b1,nrow=2)
a1

eArea(senti_mat)
#find topics
#test<-topic_wc(2,1)
#test<-test[7:65,]
#dat<-data.frame(word=test[,"word"],freq=test[,"n"])
#eWordcloud(dat, namevar = ~word, datavar = ~freq,size = c(600, 600),title = "George Washington & fist person singular",rotationRange = c(-1, 1))
[for the area plot]
x-axis:sentence number
y-axis:the weight of a certain kind of emotion being detected.
- William McKinley: The sentences using first person singular pronoun frequently also contains trust emotion.
senten_mat2<-melt(senten_mat(28))
sen_dat<-data.frame(sentence.number=senten_mat2$Var1,times=senten_mat2$value,personal_pronoun=senten_mat2$Var2,2)
senti_mat<-round(count_emo(28)[,c(1,2,4,5,7,8)],2)
rownames(senti_mat)<-seq(1,nrow(senti_mat))
senti_mat2<-melt(senti_mat)
senti_dat<-data.frame(sentence_number=senti_mat2$Var1,score=senti_mat2$value,sentiment=senti_mat2$Var2)
#par(mfrow=c(1,2))
a1<-ggplot(sen_dat,aes(sentence.number,times,fill=personal_pronoun))+geom_bar(stat="identity",position="stack")+ggtitle("")+guides(fill=guide_legend(title=NULL))+ scale_fill_brewer(palette = "Blues")+ xlab("sentence number")
#b1<-ggplot(senti_dat, aes(x = sentence_number, y = score, fill = sentiment)) +
# geom_area()
# + scale_fill_brewer(palette = "RdBu", breaks = rev(c(factor(sentiment))))
#b1<-ggplot(senti_dat,aes(x = sentence_number, y = score, fill = sentiment))+geom_bar(stat="identity",position="stack")+ggtitle("")+guides(fill=guide_legend(title=NULL))
#grid.arrange(a1,b1,nrow=2)
a1

eArea(senti_mat)
#find_sen(28,134)
#find_sen(28,135)
#find_sen(28,136)
#find_sen(28,137)
#test<-topic_wc(28,1)[1:60,]
#test<-test[6:60,]
#dat<-data.frame(word=test[,"word"],freq=test[,"n"])
#eWordcloud(dat, namevar = ~word, datavar = ~freq,size = c(600, 600),title = "WilliamMcKinley & fist person singular",rotationRange = c(-1, 1))
Finding 2 :first plural form always convey positive emotions.
senten_mat2<-melt(senten_mat(45))
sen_dat<-data.frame(sentence.number=senten_mat2$Var1,times=senten_mat2$value,personal_pronoun=senten_mat2$Var2)
par(mfrow=c(4,1), mar=c(1,0,2,0), bty="n", xaxt="n", yaxt="n", font.main=1)
a2<-ggplot(sen_dat,aes(sentence.number,times,fill=personal_pronoun))+geom_bar(stat="identity",position="stack")+ggtitle("")+guides(fill=guide_legend(title=NULL))+
scale_fill_brewer(palette = "Blues")+ xlab("sentence number")
senti_mat3<-round(count_emo(45)[,c(1,2,4,5,7,8)],2)
rownames(senti_mat3)<-seq(1,nrow(senti_mat3))
senti_mat4<-melt(senti_mat3)
senti_dat2<-data.frame(sentence_number=senti_mat4$Var1,score=senti_mat4$value,sentiment=senti_mat4$Var2)
#b2<-ggplot(senti_dat2, aes(x = sentence_number, y = score, fill = sentiment)) +
# geom_area()
#b2<-ggplot(senti_dat2,aes(x = sentence_number, y = score, fill = sentiment))+geom_bar(stat="identity",position="stack")+ggtitle("")+guides(fill=guide_legend(title=NULL))
a2
senten_mat2<-melt(senten_mat(45))
sen_dat<-data.frame(sentence.number=senten_mat2$Var1,times=senten_mat2$value,personal_pronoun=senten_mat2$Var2)
par(mfrow=c(4,1), mar=c(1,0,2,0), bty="n", xaxt="n", yaxt="n", font.main=1)
a2<-ggplot(sen_dat,aes(sentence.number,times,fill=personal_pronoun))+geom_bar(stat="identity",position="stack")+ggtitle("")+guides(fill=guide_legend(title=NULL))+
scale_fill_brewer(palette = "Blues")+ xlab("sentence number")
senti_mat3<-round(count_emo(45)[,c(1,2,4,5,7,8)],2)
rownames(senti_mat3)<-seq(1,nrow(senti_mat3))
senti_mat4<-melt(senti_mat3)
senti_dat2<-data.frame(sentence_number=senti_mat4$Var1,score=senti_mat4$value,sentiment=senti_mat4$Var2)
#b2<-ggplot(senti_dat2, aes(x = sentence_number, y = score, fill = sentiment)) +
# geom_area()
#b2<-ggplot(senti_dat2,aes(x = sentence_number, y = score, fill = sentiment))+geom_bar(stat="identity",position="stack")+ggtitle("")+guides(fill=guide_legend(title=NULL))
a2

apply(senti_mat3,2,mean)
anger anticipation fear joy surprise trust
0.01402062 0.03164948 0.03309278 0.03288660 0.01072165 0.05123711
eArea(senti_mat3)
#test<-topic_wc(45,2)[1:60,]
#dat<-data.frame(word=test[,"word"],freq=test[,"n"])
#eWordcloud(dat, namevar = ~word, datavar = ~freq)
[for the area plot]
x-axis:sentence number
y-axis:the weight of a certain kind of emotion being detected.
senten_mat2<-melt(senten_mat(57))
sen_dat<-data.frame(sentence.number=senten_mat2$Var1,times=senten_mat2$value,personal_pronoun=senten_mat2$Var2,2)
senti_mat<-round(count_emo(57)[,c(1,2,4,5,7,8)],2)
rownames(senti_mat)<-seq(1,nrow(senti_mat))
senti_mat2<-melt(senti_mat)
senti_dat<-data.frame(sentence_number=senti_mat2$Var1,score=senti_mat2$value,sentiment=senti_mat2$Var2)
#par(mfrow=c(1,2))
a1<-ggplot(sen_dat,aes(sentence.number,times,fill=personal_pronoun))+geom_bar(stat="identity",position="stack")+ggtitle("")+guides(fill=guide_legend(title=NULL))+ scale_fill_brewer(palette = "Blues")+ xlab("sentence number")
#b1<-ggplot(senti_dat, aes(x = sentence_number, y = score, fill = sentiment)) +
# geom_area()
# + scale_fill_brewer(palette = "RdBu", breaks = rev(c(factor(sentiment))))
#b1<-ggplot(senti_dat,aes(x = sentence_number, y = score, fill = sentiment))+geom_bar(stat="identity",position="stack")+ggtitle("")+guides(fill=guide_legend(title=NULL))
#grid.arrange(a1,b1,nrow=2)
a1

eArea(senti_mat)
#find_sen(28,134)
#find_sen(28,135)
#find_sen(28,136)
#find_sen(28,137)
apply(senti_mat,2,mean)
anger anticipation fear joy surprise trust
0.01561905 0.03638095 0.02866667 0.03800000 0.01390476 0.04952381
#test<-topic_wc(35,2)[1:60,]
#dat<-data.frame(word=test[,"word"],freq=test[,"n"])
#eWordcloud(dat, namevar = ~word, datavar = ~freq)
Finding 3 : Anger often begin with third person form.
senten_mat2<-melt(senten_mat(21))
sen_dat<-data.frame(sentence.number=senten_mat2$Var1,times=senten_mat2$value,personal_pronoun=senten_mat2$Var2)
a3<-ggplot(sen_dat,aes(sentence.number,times,fill=personal_pronoun))+geom_bar(stat="identity",position="stack")+ggtitle("")+guides(fill=guide_legend(title=NULL))+ scale_fill_brewer(palette = "Blues")+ xlab("sentence number")
senti_mat5<-round(count_emo(21)[,c(1,2,4,5,7,8)],2)
rownames(senti_mat5)<-seq(1,nrow(senti_mat5))
senti_mat6<-melt(senti_mat5)
senti_dat3<-data.frame(sentence_number=senti_mat6$Var1,score=senti_mat6$value,sentiment=senti_mat6$Var2)
b3<-ggplot(senti_dat3,aes(x = sentence_number, y = score, fill = sentiment))+geom_bar(stat="identity",position="stack")+ggtitle("")+guides(fill=guide_legend(title=NULL))
#b3<-ggplot(senti_dat3, aes(x = sentence_number, y = score, fill = sentiment)) +
# geom_area()
a3

eArea(senti_mat5)
apply(senti_mat5,2,mean,na.rm=T)
anger anticipation fear joy surprise trust
0.01704082 0.04326531 0.03316327 0.04204082 0.01255102 0.08020408
#test<-topic_wc(57,2)[1:60,]
#dat<-data.frame(word=test[,"word"],freq=test[,"n"])
#eWordcloud(dat, namevar = ~word, datavar = ~freq)
[for the area plot]
x-axis:sentence number
y-axis:the weight of a certain kind of emotion being detected.
senten_mat2<-melt(senten_mat(43))
sen_dat<-data.frame(sentence.number=senten_mat2$Var1,times=senten_mat2$value,personal_pronoun=senten_mat2$Var2)
a3<-ggplot(sen_dat,aes(sentence.number,times,fill=personal_pronoun))+geom_bar(stat="identity",position="stack")+ggtitle("")+guides(fill=guide_legend(title=NULL))+ scale_fill_brewer(palette = "Blues")+ xlab("sentence number")
senti_mat5<-round(count_emo(43)[,c(1,2,4,5,7,8)],2)
rownames(senti_mat5)<-seq(1,nrow(senti_mat5))
senti_mat6<-melt(senti_mat5)
senti_dat3<-data.frame(sentence_number=senti_mat6$Var1,score=senti_mat6$value,sentiment=senti_mat6$Var2)
b3<-ggplot(senti_dat3,aes(x = sentence_number, y = score, fill = sentiment))+geom_bar(stat="identity",position="stack")+ggtitle("")+guides(fill=guide_legend(title=NULL))
#b3<-ggplot(senti_dat3, aes(x = sentence_number, y = score, fill = sentiment)) +
# geom_area()
a3

eArea(senti_mat5)
apply(senti_mat5,2,mean,na.rm=T)
anger anticipation fear joy surprise trust
0.01704082 0.04326531 0.03316327 0.04204082 0.01255102 0.08020408
#test<-topic_wc(57,2)[1:60,]
#dat<-data.frame(word=test[,"word"],freq=test[,"n"])
#eWordcloud(dat, namevar = ~word, datavar = ~freq)
Part 6 - Next step
Collect more data for other formal speeches to gain more convincing analysis.
Smooth the emotion function to make it more clear.<4>
LS0tCm91dHB1dDoKICBodG1sX25vdGVib29rOiBkZWZhdWx0CiAgaHRtbF9kb2N1bWVudDogZGVmYXVsdAogIHBkZl9kb2N1bWVudDogZGVmYXVsdAotLS0KPGRpdiBpZD0iaGVhZGVyIj4KPGgxIGNsYXNzPSJ0aXRsZSI+PGI+PGZvbnQgZmFjZT0iVGltZXMgTmV3IFJvbWFuIj5UaGUgdXNlIG9mIHBlcnNvbmFsIHByb25vdW4gaW4gSW5hdWd1cmFsIFNwZWVjaGVzPC9mb250PjwvYj48L2gxPgo8aDQgY2xhc3M9ImF1dGhvciI+PGVtPjxmb250IGZhY2U9IlRpbWVzIE5ldyBSb21hbiI+WWl0b25nIEh1PC9mb250PjwvZW0+PC9oND4KPGg0IGNsYXNzPSJkYXRlIj48ZW0+PGZvbnQgZmFjZT0iVGltZXMgTmV3IFJvbWFuIj5GZWJydWFyeSAzcmQuIDIwMTc8L2ZvbnQ+PC9lbT48L2g0Pgo8L2Rpdj4KPGRpdiBzdHlsZT0idGV4dC1hbGlnbjpjZW50ZXIiPiFbaW1hZ2VdKC4uL2ZpZ3MvcGVyc29uYWxwcm8uanBlZyk8L2Rpdj4KCjxoMz48Zm9udCBmYWNlPSJUaW1lcyBOZXcgUm9tYW4iPlBhcnQgMCAtIFRvcGljIGludHJvZHVjdGlvbjwvZm9udD48L2gzPgo8cD5QZW9wbGUgYWx3YXlzIHVzZSBhIGxvdCBvZiBwZXJzb25hbCBwcm9ub3VucyB0byBhdm9pZCByZXBlYXRpbmcgc29tZW9uZeKAmXMgbmFtZXMgdGltZSBhbmQgdGltZSBhZ2Fpbi4gRGlmZmVyZW50IHBlb3BsZSBtYXkgdXNlIGRpZmZlcmVudCBwZXJzb25hbCBwcm9ub3VucyBmb3IgZGlmZmVyZW50IHdlaWdodCBpbiBkaWZmZXJlbnQgc2l0dWF0aW9uIHRvIGRlbW9uc3RyYXRlIGRpZmZlcmVudCBtZWFuaW5ncyBhbmQgZW1vdGlvbnMuIFdoYXQgYWJvdXQgdGhlIHNpdHVhdGlvbnMgaW4gcHJlc2lkZW50cycgSW5hdWd1cmFsIFNwZWVjaGVzPzwvcD4KCgo8aDM+PGZvbnQgZmFjZT0iVGltZXMgTmV3IFJvbWFuIj5QYXJ0IDEgLSBQYWNrYWdlcyBwcmVwYXJhaW9uPC9mb250PjwvaDM+CgpgYGB7cixtZXNzYWdlPUYsd2FybmluZz1GfQpwYWNrYWdlcy51c2VkPWMoIlJDb2xvckJyZXdlciIsInFkYXAiLCJnZ3Bsb3QyIiwicmVzaGFwZTIiLCJzeXV6aGV0IiwidG0iLCJxZGFwIiwicmVzaGFwZTIiLCJncmlkRXh0cmEiLCJnZ3Bsb3QyIiwid29yZGNsb3VkIiwiZHBseXIiLCJ0aWR5dGV4dCIpCgojIGNoZWNrIHBhY2thZ2VzIHRoYXQgbmVlZCB0byBiZSBpbnN0YWxsZWQuCnBhY2thZ2VzLm5lZWRlZD1zZXRkaWZmKHBhY2thZ2VzLnVzZWQsIAogICAgICAgICAgICAgICAgICAgICAgICBpbnRlcnNlY3QoaW5zdGFsbGVkLnBhY2thZ2VzKClbLDFdLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhY2thZ2VzLnVzZWQpKQojIGluc3RhbGwgYWRkaXRpb25hbCBwYWNrYWdlcwppZihsZW5ndGgocGFja2FnZXMubmVlZGVkKT4wKXsKICBpbnN0YWxsLnBhY2thZ2VzKHBhY2thZ2VzLm5lZWRlZCwgZGVwZW5kZW5jaWVzID0gVFJVRSkKfQpyZXF1aXJlKGRldnRvb2xzLHF1aWV0bHkgPSBUKQppbnN0YWxsX2dpdGh1YigncmVjaGFydHMnLCAndGFpeXVuJykKCiMgbGlicmFyeSBwYWNrYWdlcwpsaWJyYXJ5KCJSQ29sb3JCcmV3ZXIiLHF1aWV0bHkgPSBUKQpsaWJyYXJ5KCJxZGFwIixxdWlldGx5ID0gVCkKbGlicmFyeSgiZ2dwbG90MiIscXVpZXRseSA9IFQpCmxpYnJhcnkoInJlc2hhcGUyIixxdWlldGx5ID0gVCkKbGlicmFyeSgic3l1emhldCIscXVpZXRseSA9IFQpCmxpYnJhcnkoInRtIixxdWlldGx5ID0gVCkKbGlicmFyeSgicWRhcCIscXVpZXRseSA9IFQpCmxpYnJhcnkoInJlc2hhcGUyIixxdWlldGx5ID0gVCkKbGlicmFyeSgiZ3JpZEV4dHJhIixxdWlldGx5ID0gVCkKbGlicmFyeSgiZ2dwbG90MiIscXVpZXRseSA9IFQpCmxpYnJhcnkoIndvcmRjbG91ZCIscXVpZXRseSA9IFQpCmxpYnJhcnkoImRwbHlyIixxdWlldGx5ID0gVCkKbGlicmFyeSgidGlkeXRleHQiLHF1aWV0bHkgPSBUKQpsaWJyYXJ5KCJyZWNoYXJ0cyIscXVpZXRseSA9IFQpCgojcGFydCBvZiBjb2RlcyBhcmUgaW4gdGhpcyBSIGZpbGUuCnNvdXJjZSgiLi4vbGliL2N1c3RvbWl6ZWRfZnVuY3Rpb24uUiIpCmBgYAoKCjxoMz48Zm9udCBmYWNlPSJUaW1lcyBOZXcgUm9tYW4iPlBhcnQgMiAtIERhdGEgY2xlYW5pbmc8L2ZvbnQ+PC9oMz4KCjxwPldlIGNvdW50IHRoZSB3b3JkIGZyZXF1ZW5jeSBmb3IgZWFjaCBzcGVlY2hlcyBhbmQgbWFrZSB0aGlzIGRhdGEgbWF0cml4IG9uIHdoaWNoIG91ciB3aG9sZSBhbmFseXNpcyB3b3VsZCBiYXNlZC48L3A+CgpgYGB7cix3YXJuaW5nPUZ9CmluYXVnLmxpc3Q9cmVhZC5jc3YoIi4uL2RhdGEvSW5hdWd1cmF0aW9uSW5mby5jc3YiLCBzdHJpbmdzQXNGYWN0b3JzID0gRkFMU0UpCmluYXVnLmRhdGE9cmVhZC50YWJsZSgiLi4vZGF0YS9JbmF1Z3VhdGlvbkRhdGVzLnR4dCIsIHN0cmluZ3NBc0ZhY3RvcnMgPSBGQUxTRSxibGFuay5saW5lcy5za2lwPUYsc2VwPSAiXHQiKQptYXQxPC1OVUxMCgpmb3IoaSBpbiBzZXEobnJvdyhpbmF1Zy5saXN0KSkpIHsKZmlsZW5hbWUgPC0gcGFzdGUwKCIuLi9kYXRhL0luYXVndXJhbFNwZWVjaGVzL2luYXVnIiwgCiAgICAgICAgICAgICAgICAgICAgIGluYXVnLmxpc3QkRmlsZVtpXSwgIi0iLCAKICAgICAgICAgICAgICAgICAgICAgaW5hdWcubGlzdCRUZXJtW2ldLCAiLnR4dCIpCnR4IDwtIHJlYWRMaW5lcyhmaWxlbmFtZSx3YXJuPUYpCmlmIChpPT01OCkgCnsKICB0eDwtcGFzdGUodHgsIGNvbGxhcHNlID0gIiAiKQogIHR4X3dvcmRzIDwtIHN0cnNwbGl0KHR4LCBzcGxpdCA9ICIgIilbWzFdXQp9CmVsc2UKdHhfd29yZHMgPC0gc3Ryc3BsaXQodHgsIHNwbGl0ID0gIiAiKVtbMV1dCmRhdGVfcGF0dGVybjIgPC0gIlthLXpBLXpdKyIKdHhfd29yZHMyIDwtIGdyZXAodHhfd29yZHMsIHBhdHRlcm4gPSBkYXRlX3BhdHRlcm4yLCB2YWx1ZT1UKQp0eF9sb2cgPC0gZ3JlcGwodHhfd29yZHMyLCBwYXR0ZXJuID0gZGF0ZV9wYXR0ZXJuMikKbWF0Y2hlcyA8LSBncmVnZXhwcihwYXR0ZXJuID0gZGF0ZV9wYXR0ZXJuMiwgdGV4dCA9IHR4X3dvcmRzMlt0eF9sb2ddKQp0eF93b3JkcyA8LSB1bmxpc3QocmVnbWF0Y2hlcyh0eF93b3JkczJbdHhfbG9nXSwgbWF0Y2hlcykpCnR4X3dvcmRzIDwtIHVubGlzdChybV9zdG9wd29yZHModHhfd29yZHMpKQptYXQ8LU5VTEwKdGFibGU8LXRhYmxlKHR4X3dvcmRzKQp3b3JkPC1uYW1lcyh0YWJsZSkKbjwtdW5uYW1lKHRhYmxlKQptYXRuYW1lPC1wYXN0ZShpbmF1Zy5saXN0JEZpbGVbaV0saW5hdWcubGlzdCRUZXJtW2ldKQptYXQ8LWNiaW5kKHJlcChtYXRuYW1lLG5yb3cobikpLHdvcmQsbikKbWF0MTwtcmJpbmQobWF0MSxtYXQpCn0KY29sbmFtZXMobWF0MSk8LWMoIm5hbWUiLCJ3b3JkIiwibiIpIAptYXRzb3J0PC1tYXQxW29yZGVyKGFzLm51bWVyaWMobWF0MVssM10pLGRlY3JlYXNpbmcgPSBUKSxdCmhlYWQobWF0c29ydCkKYGBgCgo8aDM+PGZvbnQgZmFjZT0iVGltZXMgTmV3IFJvbWFuIj5QYXJ0IDMgLSBEaWZmZXJlbnQgcHJlc2lkZW50IHVzZXMgcGVyc29uYWwgcHJvbm91biBmb3IgZGlmZmVyZW50IHdlaWdodDwvZm9udD48L2gzPgoKPHA+SW4gdGhpcyBwYXJ0LHdlIHdpbGwgZG8gYSBnZW5lcmFsIGFuYWx5c2lzLHRvIHNlZSB0aGUgZ2VuZXJhbCB0cmVuZCBhbmQgZmluZCBkaWZmZXJlbmNlIG9mIHRoZSB3ZWlnaHQgd2hlbiBkaXZpZGVkIGJ5IGRpZmZlcmVudCBmYWN0b3JzLkJ5IHNheWluZyB3ZWlnaHQsd2UgbWVhbiB0aGUgdGltZXMgb25lIHVzaW5nIGEgY2VydGFpbiBwZXJzb25hbCBwcm9ub3VuIGRpdmlkZWQgYnkgdGhlIHRvdGFsIHRpbWVzIGhlIHVzaW5nIGFsbCBmb3VyIHR5cGVzIG9mIHByb25vdW5zLjwvcD4KPHA+V2UgZGl2aWRlIHBlcnNvbmFsIHByb25vdW5zIGludG8gNCB0eXBlcyxmaXJzdCBwZXJzb24gc2luZ3VsYXIgZm9ybSxmaXJzdCBwZXJzb24gcGx1cmFsIGZvcm0sc2Vjb25kIHBlcnNvbiBmb3JtIGFuZCB0aGlyZCBwZXJzb24gZm9ybS48L3A+CgoKPGRpdiBzdHlsZT0idGV4dC1hbGlnbjpjZW50ZXIiPiFbaW1hZ2VdKC4uL2ZpZ3MvcGVyc29uYWx0eXBlLmpwZWcpPC9kaXY+CgpgYGB7cix3YXJuaW5nPUZ9CiNwZXJzb25hbCBwcm9ub3VuCgpmaXJzdDE8LWMoIkkiLCJtZSIsIm1pbmUiLCJteSIpCmZpcnN0MjwtYygid2UiLCJvdXIiLCJvdXJzIiwidXMiKQpzZWNvbmQ8LWMoInlvdSIsInlvdXIiLCJ5b3VycyIpCnRoaXJkPC1jKCJoZSIsInNoZSIsIml0IiwiaGltIiwiaGVyIiwiaGlzIiwiaGVycyIsInRoZXkiLCJ0aGVtIiwidGhlaXIiKQpwZXJzb25hbDwtbGlzdChmaXJzdDEsZmlyc3QyLHNlY29uZCx0aGlyZCkKCnBwX21hdDwtbWF0cml4KG5yb3cgPSBucm93KGluYXVnLmxpc3QpLG5jb2wgPSA0KQpmb3IoaSBpbiBzZXEobnJvdyhpbmF1Zy5saXN0KSkpIHsKICB0ZXN0PC1tYXRzb3J0W21hdHNvcnRbLCJuYW1lIl09PXBhc3RlKGluYXVnLmxpc3QkRmlsZVtpXSxpbmF1Zy5saXN0JFRlcm1baV0pLCJ3b3JkIl0KICBwcF9tYXRbaSxdPC1maW5kX3BlcnNvbmFsX3Byb25vdW4odGVzdCkKfQpwcG5hbWU8LU5VTEwKZm9yKGkgaW4gc2VxKG5yb3coaW5hdWcubGlzdCkpKSB7CnBwbmFtZVtpXSA8LSBwYXN0ZShpbmF1Zy5saXN0JEZpbGVbaV0sIGluYXVnLmxpc3QkVGVybVtpXSkgfQpyb3duYW1lcyhwcF9tYXQpPC1wcG5hbWUKY29sbmFtZXMocHBfbWF0KTwtYygiZmlyc3QxIiwiZmlyc3QyIiwic2Vjb25kIiwidGhpcmQiKQpoZWFkKHBwX21hdCkKYGBgCgpgYGB7cn0KcHBfbWF0MTwtcHBfbWF0CnJvd25hbWVzKHBwX21hdDEpPC1zZXEoMTc4OSwyMDE3LDQpCnBwX21hdDI8LW1lbHQocHBfbWF0MSkKcHBfbWF0MzwtbWVsdChwcF9tYXQpCgpuZXcxPC1tYXQybWF0KHBwX21hdCkKYTwtZ2dwbG90KGRhdGEuZnJhbWUocGVyc29uYWxfcHJvbm91bj1uZXcxWywidHlwZSJdLG5ldzFbLCJuYW1lIl0sbmV3MVssInByb3AiXSksIGFlcyh4PWZhY3RvcihuZXcxWywibmFtZSJdLCBsZXZlbHM9dW5pcXVlKG5ldzFbLCJuYW1lIl0pKSx5PW5ldzFbLCJwcm9wIl0sIGNvbG91cj1wZXJzb25hbF9wcm9ub3VuLGdyb3VwPXBlcnNvbmFsX3Byb25vdW4pKSsgZ2VvbV9saW5lKHNpemU9MikgKyB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfYmxhbmsoKSkgKyB4bGFiKCJ0aW1lIHdpdGggZGlmZmVyZW50IHByZXNpZGVudHMiKSArIHlsYWIoInByb3BvcnRpb24iKSAKCnBwX2RhdDwtZGF0YS5mcmFtZSh5ZWFyPXBwX21hdDIkVmFyMSxwcm9wb3J0aW9uPXBwX21hdDIkdmFsdWUscGVyc29uYWxfcHJvbm91bj1wcF9tYXQyJFZhcjIpCmI8LWdncGxvdChwcF9kYXQsIGFlcyh4ID0geWVhciwgeSA9IHByb3BvcnRpb24sIGZpbGwgPSBwZXJzb25hbF9wcm9ub3VuKSkgKwogIGdlb21fYXJlYSgpICsKICBzY2FsZV9maWxsX2JyZXdlcihwYWxldHRlID0gIkJsdWVzIiwgYnJlYWtzID0gcmV2KGMoInRoaXJkIiwic2Vjb25kIiwiZmlyc3QyIiwiZmlyc3QxIikpKQoKcHBfZGF0PC1kYXRhLmZyYW1lKHByZXNpZGVudD1wcF9tYXQzJFZhcjEscHJvcG9ydGlvbj1wcF9tYXQyJHZhbHVlLHBlcnNvbmFsX3Byb25vdW49cHBfbWF0MiRWYXIyKQpjPC1nZ3Bsb3QocHBfZGF0LGFlcyhwcmVzaWRlbnQscHJvcG9ydGlvbixmaWxsPXBlcnNvbmFsX3Byb25vdW4pKStnZW9tX2JhcihzdGF0PSJpZGVudGl0eSIscG9zaXRpb249InN0YWNrIikrZ2d0aXRsZSgiIikrZ3VpZGVzKGZpbGw9Z3VpZGVfbGVnZW5kKHRpdGxlPU5VTEwpKSsKICBzY2FsZV9maWxsX2JyZXdlcihwYWxldHRlID0gIkJsdWVzIikrIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF9ibGFuaygpKSArIHhsYWIoInRpbWUgd2l0aCBkaWZmZXJlbnQgcHJlc2lkZW50cyIpCiNncmlkLmFycmFuZ2UoYixjLG5yb3c9MikKYGBgCgo8cD5Ob3RpY2U6VGhlIHBsb3QoYW5kIHNvbWUgZm9sbG93aW5nIHBsb3RzKSBhcmUgaW50ZXJhY3RpdmUgYnkgbW92aW5nIHlvdXIgbW91c2UgdG8gYSBjZXJ0YWluIGRhdGEgcG9pbnQsZGV0YWlscyBjYW4gYmUgc2hvd24uPC9wPgoKPGg0PjMuMSBHZW5lcmFsIFRyZW5kPC9oND4KCngtYXhpczp0aW1lIChkaWZmZXJlbnQgcHJlc2lkZW50cykKeS1heGlzOnRoZSB3ZWlnaHQgb2YgYSBjZXJ0YWluIGtpbmQgb2YgcGVyc29uYWwgcHJvbm91biBiZWluZyB1c2VkLgoKYGBge3J9CmVBcmVhKHBwX21hdDEpCmBgYAo8cD5JbiBnZW5lcmFsPC9wPgorIFRoZXJlIGlzIG5vIG9idmlvdXMgdHJlbmQsanVzdCBzb21lIGZsdWN0dWF0aW9ucyBmb3Igc2Vjb25kICYgdGhpcmQgcGVyc29uIHVzaW5nIHdlaWdodC4KKyBUaGVyZSBpcyBhIHNsaWdodGx5IGRlY3JlYXNpbmcgZm9yIGZpcnN0IHBlcnNvbiBzaW5ndWxhciBmb3JtIHVzaW5nIHdlaWdodC4KKyBUaGVyZSBpcyBhIHNsaWdodGx5IGluY3JlYXNpbmcgZm9yIGZpcnN0IHBlcnNvbiBwbHVyYWwgZm9ybSB1c2luZyB3ZWlnaHQuCgo8cD5JdCdzIHF1aXRlIHJlYXNvbmFibGUsc2luY2UgcHJlc2lkZW50cyBjb21lIHRvIHJlYWxpemUgdGhhdCB0aGV5IHNob3VsZCBlbXBoYXNpemUgcGVvcGxlJ3MgcmlnaHRzIGFuZCByZXNwb25zaWJpbGl0aWVzIHRvIGxldCBwZW9wbGUgZmVlbCB0aGF0IHRoZXkgYXJlIGJlaW5nIHRvZ2V0aGVyLHRoZSBpbnRlcmVzdHMgb2YgZXZlcnkgY2l0aXplbnMgYXJlIGNsb3NlbHkgcmVsYXRlZCB0byBkZXN0aW55IG9mIHRoZSBVbml0ZWQgU3RhdGVzLHJhdGhlciB0aGFuIGp1c3QgdGFsa2luZyBhYm91dCB0aGVtc2VsdmVzLjwvcD4KCgo8aDQ+My4yIENvbXBhcmluZyBiZXR3ZWVuIGRpZmZlcmVudCB0ZXJtczwvaDQ+CgoKYGBge3Isd2FybmluZz1GfQojZGlmZmVyZW50IHRlcm0gCmF2ZzwtYXBwbHkocHBfbWF0LDIsbWVhbikKbGlzdDwtdGVybV9zZXAoKQphdmdfdGVybTE8LWFwcGx5KHBwX21hdFtsaXN0W1sxXV0sXSwyLG1lYW4pCmF2Z190ZXJtMjwtYXBwbHkocHBfbWF0W2xpc3RbWzJdXSxdLDIsbWVhbikKZGYxPC1kYXRhLmZyYW1lKGF2ZyxhdmdfdGVybTEsYXZnX3Rlcm0yKQpkYXQ8LXQoZGYxKQpteWRhdDwtbWVsdChkYXQpCiNteWRhdApteWRhdDwtZGF0YS5mcmFtZSh0ZXJtID0gbXlkYXQkVmFyMSxwZXJzb25hbF9wcm9ub3VuID0gbXlkYXQkVmFyMixwcm9wb3J0aW9uPXJvdW5kKG15ZGF0JHZhbHVlLDIpKQpnZ3Bsb3QobXlkYXQsYWVzKHRlcm0scHJvcG9ydGlvbixmaWxsPXBlcnNvbmFsX3Byb25vdW4pKStnZW9tX2JhcihzdGF0PSJpZGVudGl0eSIscG9zaXRpb249InN0YWNrIikrZ2d0aXRsZSgiIikrdGhlbWUoYXhpcy50aWNrcy5sZW5ndGg9dW5pdCgwLjUsJ2NtJykpK2d1aWRlcyhmaWxsPWd1aWRlX2xlZ2VuZCh0aXRsZT1OVUxMKSkrCiAgc2NhbGVfZmlsbF9icmV3ZXIocGFsZXR0ZSA9ICJCbHVlcyIpCmVSYWRhcih4dGFicyggcHJvcG9ydGlvbn4gdGVybStwZXJzb25hbF9wcm9ub3VuLCBteWRhdCkpCmBgYAo8cD5Gcm9tIHByZXNpZGVudCdzIHRlcm0gMSB0byB0ZXJtIDIsdGhleSB0ZW5kIHRvIHVzZSBtb3JlIGZpcnN0IHBlcnNvbiBwbHVyYWwgZm9ybSB0aGFuIGZpcnN0IHBlcnNvbiBzaW5ndWxhciBmb3JtLkl0J3MgYWxzbyByZWFzb25hYmxlLCBzaW5jZSB0aGUgcHJlc2lkZW50IGFuZCB0aGUgcHVibGljIGJlY29tZSBmYW1pbGlhciB0byBlYWNoIG90aGVyLHNvIHRoZSBwcmVzaWRlbnQgbmF0dXJhbGx5IHRha2UgaGltc2VsZiBhbmQgdGhlIHB1YmxpYyBhcyBhIHdob2xlIGdyb3VwLjwvcD4KCgo8aDQ+My4zIENvbXBhcmluZyBhbW9uZyBkaWZmZXJlbnQgcGFydGllczwvaDQ+CgoKYGBge3Isd2FybmluZz1GfQojZGlmZmVyZW50IHBhcnR5Cm5ld19pbmF1Zy5saXN0PC1jYmluZChpbmF1Zy5saXN0LHBwX21hdCkKZmlyc3QxPC10YXBwbHkobmV3X2luYXVnLmxpc3QkZmlyc3QxLG5ld19pbmF1Zy5saXN0JFBhcnR5LG1lYW4pCmZpcnN0MjwtdGFwcGx5KG5ld19pbmF1Zy5saXN0JGZpcnN0MixuZXdfaW5hdWcubGlzdCRQYXJ0eSxtZWFuKQpzZWNvbmQ8LXRhcHBseShuZXdfaW5hdWcubGlzdCRzZWNvbmQsbmV3X2luYXVnLmxpc3QkUGFydHksbWVhbikKdGhpcmQ8LXRhcHBseShuZXdfaW5hdWcubGlzdCR0aGlyZCxuZXdfaW5hdWcubGlzdCRQYXJ0eSxtZWFuKQojaGVhZChuZXdfaW5hdWcubGlzdCkKI2FnZ3JlZ2F0ZShuZXdfaW5hdWcubGlzdCwpCmRhdDwtcmJpbmQodW5uYW1lKGZpcnN0MSksdW5uYW1lKGZpcnN0MiksdW5uYW1lKHNlY29uZCksdW5uYW1lKHRoaXJkKSkKY29sbmFtZXMoZGF0KTwtbmFtZXMoZmlyc3QxKQpyb3duYW1lcyhkYXQpPC1jKCJmaXJzdDEiLCJmaXJzdDIiLCJzZWNvbmQiLCJ0aGlyZCIpCm15ZGF0PC1tZWx0KGRhdCkKbXlkYXQ8LWRhdGEuZnJhbWUocGVyc29uYWxfcHJvbm91biA9IG15ZGF0JFZhcjEsIHBhcnR5ID0gbXlkYXQkVmFyMixwcm9wb3J0aW9uPXJvdW5kKG15ZGF0JHZhbHVlLDIpKQpnZ3Bsb3QobXlkYXQsYWVzKHBhcnR5LHByb3BvcnRpb24sZmlsbD1wZXJzb25hbF9wcm9ub3VuKSkrZ2VvbV9iYXIoc3RhdD0iaWRlbnRpdHkiLHBvc2l0aW9uPSJzdGFjayIpK2dndGl0bGUoIiIpK3RoZW1lKGF4aXMudGlja3MubGVuZ3RoPXVuaXQoMC41LCdjbScpKStndWlkZXMoZmlsbD1ndWlkZV9sZWdlbmQodGl0bGU9TlVMTCkpKwogIHNjYWxlX2ZpbGxfYnJld2VyKHBhbGV0dGUgPSAiQmx1ZXMiKSsgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSAxNSwgaGp1c3QgPSAwLjUsIHZqdXN0ID0gMC41KSkKZVJhZGFyKHh0YWJzKCBwcm9wb3J0aW9ufiBwYXJ0eStwZXJzb25hbF9wcm9ub3VuLCBteWRhdCkpCmBgYAo8cD5BcyB0aGUgcGxvdCBzaG93bixXaGlnIHVzZWQgZmlyc3QgcGVyc29uIHNpbmd1bGFyIGZvcm0gYW5kIHRoaXJkIHBlcnNvbiBtb3N0IGZyZXF1ZW50bHksdXNlZCBmaXJzdCBwZXJzb24gcGx1cmFsIGZvcm0gYXMgd2VsbCBhcyBzZWNvbmQgcGVyc29uIGF0IGxlYXN0IGZyZXF1ZW5jeS5XaGlsZSBmZWRlcmFsaXN0IGlzIGFsbW9zdCB0aGUgb3Bwb3NpdGUuPC9wPgoKCjxoMz48Zm9udCBmYWNlPSJUaW1lcyBOZXcgUm9tYW4iPlBhcnQgNCAtIEFuYWx5c2lzIG9uIGVhY2gga2luZCBvZiBwZXJzb25hbCBwcm9ub3VuJ3MgQ1JBWlkgRkFOPC9mb250PjwvaDM+Cgo8cD5JbiB0aGlzIHBhcnQsIHdlIHN3aXRjaCBvdXIgYW5hbHlzaXMgZnJvbSB0aGUgb3ZlcmFsbCBkYXRhIHRvIHNvbWUgZXh0cmVtZSBwb2ludHMsIHRvIGFuYWx5c2lzIHRoZSBmZWF0dXJlcyBhYm91dCB0aG9zZSBwcmVzaWRlbnRzIHdobyB1c2UgYSBjZXJ0YWluIHR5cGUgb2YgcGVyc29uYWwgcHJvbm91biBhdCBhIGhpZ2ggZnJlcXVlbmN5LGxpa2UgdG9wIDEwLjwvcD4KYGBge3Isd2FybmluZz1GfQpkYXRhMTwtcHBfbWF0W29yZGVyKHBwX21hdFssMV0sZGVjcmVhc2luZyA9IFQpLF1bMToxMCxdCmRhdGEyPC1wcF9tYXRbb3JkZXIocHBfbWF0WywyXSxkZWNyZWFzaW5nID0gVCksXVsxOjEwLF0KZGF0YTM8LXBwX21hdFtvcmRlcihwcF9tYXRbLDNdLGRlY3JlYXNpbmcgPSBUKSxdWzE6MTAsXQpkYXRhNDwtcHBfbWF0W29yZGVyKHBwX21hdFssNF0sZGVjcmVhc2luZyA9IFQpLF1bMToxMCxdCm5ldzE8LW1hdDJtYXQoZGF0YTEpCm5ldzI8LW1hdDJtYXQoZGF0YTIpCm5ldzM8LW1hdDJtYXQoZGF0YTMpCm5ldzQ8LW1hdDJtYXQoZGF0YTQpCm5ldzE8LWRhdGEuZnJhbWUodHlwZT1uZXcxWywidHlwZSJdLG5hbWU9bmV3MVssIm5hbWUiXSxwcm9wb3J0aW9uPWFzLm51bWVyaWMobmV3MVssInByb3AiXSkpCm5ldzI8LWRhdGEuZnJhbWUodHlwZT1uZXcyWywidHlwZSJdLG5hbWU9bmV3MlssIm5hbWUiXSxwcm9wb3J0aW9uPWFzLm51bWVyaWMobmV3MlssInByb3AiXSkpCm5ldzM8LWRhdGEuZnJhbWUodHlwZT1uZXczWywidHlwZSJdLG5hbWU9bmV3M1ssIm5hbWUiXSxwcm9wb3J0aW9uPWFzLm51bWVyaWMobmV3M1ssInByb3AiXSkpCm5ldzQ8LWRhdGEuZnJhbWUodHlwZT1uZXc0WywidHlwZSJdLG5hbWU9bmV3NFssIm5hbWUiXSxwcm9wb3J0aW9uPWFzLm51bWVyaWMobmV3NFssInByb3AiXSkpCmluYXVnLmxpc3Q9cmVhZC5jc3YoIi4uL2RhdGEvSW5hdWd1cmF0aW9uSW5mby5jc3YiLCBzdHJpbmdzQXNGYWN0b3JzID0gRkFMU0UpCmluYXVnLmRhdGE9cmVhZC50YWJsZSgiLi4vZGF0YS9JbmF1Z3VhdGlvbkRhdGVzLnR4dCIsIHN0cmluZ3NBc0ZhY3RvcnMgPSBGQUxTRSxibGFuay5saW5lcy5za2lwPUYsc2VwPSAiXHQiKQpmaXJzdDE8LWMoIkkiLCJtZSIsIm1pbmUiLCJteSIpCmZpcnN0MjwtYygid2UiLCJvdXIiLCJvdXJzIiwidXMiKQpzZWNvbmQ8LWMoInlvdSIsInlvdXIiLCJ5b3VycyIpCnRoaXJkPC1jKCJoZSIsInNoZSIsIml0IiwiaGltIiwiaGVyIiwiaGlzIiwiaGVycyIsInRoZXkiLCJ0aGVtIiwidGhlaXIiKQpwZXJzb25hbDwtbGlzdChmaXJzdDEsZmlyc3QyLHNlY29uZCx0aGlyZCkKc3BlZWNoLmxpc3Q9cmVhZC5jc3YoIi4uL2RhdGEvSW5hdWd1cmF0aW9uSW5mby5jc3YiLCBzdHJpbmdzQXNGYWN0b3JzID0gRkFMU0UpCnNwZWVjaC5saXN0JHR5cGU9YyhyZXAoImluYXVnIiwgbnJvdyhzcGVlY2gubGlzdCkpKQpzcGVlY2gubGlzdCRmdWxsdGV4dD1OQQpzZW50ZW5jZS5saXN0PU5VTEwKYGBgCgoKPGg0PjQuMSBUb3AgdGVuIHVzaW5nIGZpcnN0IHBlcnNvbiBzaW5ndWxhciBmb3JtPC9oND4KCisgeC1heGlzOmRpZmZlcmVudCBwcmVzaWRlbnRzCisgeS1heGlzOnRoZSB3ZWlnaHQgb2YgYSBjZXJ0YWluIGtpbmQgb2YgcGVyc29uYWwgcHJvbm91biBiZWluZyB1c2VkLgoKYGBge3J9CmVCYXIobmV3MSwgfm5hbWUsIH5wcm9wb3J0aW9uLCB+dHlwZSkKYGBgCgpgYGB7cn0KdGVzdDwtdG9waWNfd2MoMiwxKQpkYXQ8LWRhdGEuZnJhbWUod29yZD10ZXN0Wywid29yZCJdLGZyZXE9NSphcy5udW1lcmljKHRlc3RbLCJuIl0pKQojcGFyKG1mcm93PWMoMSwyKSkKZVdvcmRjbG91ZChkYXRbNzo2NSxdLCBuYW1ldmFyID0gfndvcmQsIGRhdGF2YXIgPSB+ZnJlcSxzaXplID0gYyg2MDAsIDYwMCksdGl0bGUgPSAiR2VvcmdlIFdhc2hpbmd0b24gJiBmaXJzdCBwZXJzb24gc2luZ3VsYXIiLHJvdGF0aW9uUmFuZ2UgPSBjKC0xLCAxKSkKdGVzdDwtdG9waWNfd2MoMiwzKQpkYXQ8LWRhdGEuZnJhbWUod29yZD10ZXN0Wywid29yZCJdLGZyZXE9NSphcy5udW1lcmljKHRlc3RbLCJuIl0pKQplV29yZGNsb3VkKGRhdFsyOjMyLF0sIG5hbWV2YXIgPSB+d29yZCwgZGF0YXZhciA9IH5mcmVxLHNpemUgPSBjKDYwMCwgNjAwKSx0aXRsZSA9ICJHZW9yZ2UgV2FzaGluZ3RvbiAmIHNlY29uZCBwZXJzb24iLHJvdGF0aW9uUmFuZ2UgPSBjKC0xLCAxKSkKYGBgCjxwPk5vLjEgImZpcnN0IHBlcnNvbiBzaW5ndWxhciB1c2VyIiBpcyBHZW9yZ2UgV2FzaGluZ3Rvbih0ZXJtIDIpLlRoZSA2NyUgcGVyc29uYWwgcHJvbm91biBHZW9yZ2UgV2FzaGluZ3RvbiB1c2VkIGluIGhpcyBzZWNvbmQgcGVyc29uIGlzIGZpcnN0IHBlcnNvbiBzaW5ndWxhciBmb3JtLiBIZSBhbHNvIHVzZWQgc2Vjb25kIHBlcnNvbiBxdWl0ZSBmcmVxdWVudGx5IGF0IGFib3V0IDMzJS4gQWxvbmcgd2l0aCB0aGUgd29yZCBjbG91ZCx3ZSBjYW4gc3BlY3VsYXRlIGluIGhpcyBzcGVlY2hlcyxubyBtYXR0ZXIgdXNpbmcgZmlyc3Qgc2luZ3VsYXIgZm9ybSBvciBzZWNvbmQgZm9ybSxoZSB1c2VkIHdvcmRzIGxpa2UgImFkbWluaXN0cmF0aW9uIiwiY2hpZWYiLGl0IHdhcyBzaG93biB0aGF0IGhlIHRvb2sgaGltc2VsZiBhcyBhIGxlYWRlciBhbmQgd2FudGVkIHRvIGV4cHJlc3MgaGlzIHBvd2VyIHRvIHB1YmxpYy48L3A+CgpgYGB7cn0KdGVzdDwtbWF0c29ydFttYXRzb3J0WywibmFtZSJdID09ICJXaWxsaWFtTWNLaW5sZXkgMSIsXQp0ZXN0MTwtbWF0c29ydFttYXRzb3J0WywibmFtZSJdID09ICJXb29kcm93V2lsc29uIDIiLF0KdGVzdDI8LW1hdHNvcnRbbWF0c29ydFssIm5hbWUiXSA9PSAiSmFtZXNCdWNoYW5hbiAxIixdCnRlc3Q8LXJiaW5kKHRlc3QsdGVzdDEsdGVzdDIpCnRlc3Q8LXRlc3Rbb3JkZXIoYXMubnVtZXJpYyh0ZXN0WywzXSksZGVjcmVhc2luZyA9IFQpLF0KdGVzdDwtdGVzdFsxNzoyNTI5LF0KZGF0PC1kYXRhLmZyYW1lKHdvcmQ9dGVzdFssIndvcmQiXSxmcmVxPXRlc3RbLCJuIl0pCiNwYXIobWZyb3c9YygxLDIpKQplV29yZGNsb3VkKGRhdCwgbmFtZXZhciA9IH53b3JkLCBkYXRhdmFyID0gfmZyZXEsc2l6ZSA9IGMoNjAwLCA2MDApLHRpdGxlID0gIldpbGxpYW1NY0tpbmxleSAxICYgV29vZHJvd1dpbHNvbiAyICYgSmFtZXNCdWNoYW5hbiAxIixyb3RhdGlvblJhbmdlID0gYygtMSwgMSkpCmBgYAo8cD5FeGNlcHQgV2FzaGluZ3Rvbixmcm9tIE5vLjIgV2lsbGlhbSBNY0tpbmxleSh0ZXJtIDEpIHRvIE5vLjQgSmFtZXMgQnVjaGFuYW4odGVybSAxKSx0aGV5IGRpZG4ndCBldmVuIHVzZSBzZWNvbmQgcGVyc29uLkFkZCB0aGVpciB0aHJlZSdzIHNwZWVjaGVzIHRvIG1ha2UgdGhlIHdvcmRjbG91ZCx3ZSBjYW4gaGFyZGx5IGZpbmQgdGhlIHdvcmRzIGRlbW9uc3RyYXRpbmcgY2VudHJhbGl6YXRpb24gb2YgcG93ZXIsIGluc3RlYWQsdGhlcmUgYXJlIHdvcmRzIGxpa2UgImNvbmdyZXNzIiwiZmFpciIsImNpdmlsIiwibGlmZSIsc2hvd2luZyBtb3JlIGdlbnRsZSBlbW90aW9uLjwvcD4KPGg0PjQuMiBUb3AgdGVuIHVzaW5nIGZpcnN0IHBlcnNvbiBwbHVyYWwgZm9ybTwvaDQ+CgorIHgtYXhpczpkaWZmZXJlbnQgcHJlc2lkZW50cworIHktYXhpczp0aGUgd2VpZ2h0IG9mIGEgY2VydGFpbiBraW5kIG9mIHBlcnNvbmFsIHByb25vdW4gYmVpbmcgdXNlZC4KCmBgYHtyfQplQmFyKG5ldzIsIH5uYW1lLCB+cHJvcG9ydGlvbiwgfnR5cGUpCmBgYAoKCmBgYHtyfQp0ZXN0PC1tYXRzb3J0W21hdHNvcnRbLCJuYW1lIl0gPT0gIkZyYW5rbGluRFJvb3NldmVsdCAzIixdCnRlc3QxPC1tYXRzb3J0W21hdHNvcnRbLCJuYW1lIl0gPT0gIlRoZW9kb3JlUm9vc2V2ZWx0IDEiLF0KdGVzdDI8LW1hdHNvcnRbbWF0c29ydFssIm5hbWUiXSA9PSAiQW5kcmV3SmFja3NvbiAxIixdCnRlc3QzPC1tYXRzb3J0W21hdHNvcnRbLCJuYW1lIl0gPT0gIkFicmFoYW1MaW5jb2xuIDIiLF0KdGVzdDQ8LW1hdHNvcnRbbWF0c29ydFssIm5hbWUiXSA9PSAiV2lsbGlhbU1jS2lubGV5IDIiLF0KdGVzdDU8LW1hdHNvcnRbbWF0c29ydFssIm5hbWUiXSA9PSAiRnJhbmtsaW5EUm9vc2V2ZWx0IDQiLF0KdGVzdDwtcmJpbmQodGVzdCx0ZXN0MSx0ZXN0Mix0ZXN0Myx0ZXN0NCx0ZXN0NSkKdGVzdDwtdGVzdFtvcmRlcihhcy5udW1lcmljKHRlc3RbLDNdKSxkZWNyZWFzaW5nID0gVCksXQp0ZXN0PC10ZXN0WzQwOjI2MzgsXQpkYXQ8LWRhdGEuZnJhbWUod29yZD10ZXN0Wywid29yZCJdLGZyZXE9dGVzdFssIm4iXSkKI3BhcihtZnJvdz1jKDEsMikpCmVXb3JkY2xvdWQoZGF0LCBuYW1ldmFyID0gfndvcmQsIGRhdGF2YXIgPSB+ZnJlcSxzaXplID0gYyg2MDAsIDYwMCksdGl0bGUgPSAiVE9QIDYgdXNpbmcgZmlyc3QgcGVyc29uIHBsdXJhbCBmb3JtIixyb3RhdGlvblJhbmdlID0gYygtMSwgMSkpCmBgYAoKPHA+Rm9yIHByZXNpZGVudHMgZnJlcXVlbnRseSB1c2luZyBmaXJzdCBwZXJzb24gcGx1cmFsIGZvcm0sIHRoZXJlIGV4aXN0cyBzaW1pbGFyIHBoZW5vbWVub24uRnJvbSBOby4xIEZyYW5rbGluIERSb29zZXZlbHQodGVybSAzKSB0byBOby42IEZyYW5rbGluIERSb29zZXZlbHQodGVybSA0KSx0aGV5IGFsc28gbWFrZSB0aGUgc3BlZWNoZXMgd2l0aG91dCB1c2luZyBzZWNvbmQgcGVyc29uLkFkZCB0aGVpciBzcGVlY2hlcyB0byBtYWtlIHRoZSB3b3JkY2xvdWQsd2UgZmluZCBzaW1pbGFyIHdvcmRzIHNob3dpbmcgZ2VudGxlIGVtb3Rpb24uPC9wPgoKPGg0PjQuMyBUb3AgdGVuIHVzaW5nIHNlY29uZCBwZXJzb248L2g0PgoKKyB4LWF4aXM6ZGlmZmVyZW50IHByZXNpZGVudHMKKyB5LWF4aXM6dGhlIHdlaWdodCBvZiBhIGNlcnRhaW4ga2luZCBvZiBwZXJzb25hbCBwcm9ub3VuIGJlaW5nIHVzZWQuCgpgYGB7cn0KZUJhcihuZXczLCB+bmFtZSwgfnByb3BvcnRpb24sIH50eXBlKQpgYGAKPGg0PjQuNCBUb3AgdGVuIHVzaW5nIHRoaXJkIHBlcnNvbjwvaDQ+CgorIHgtYXhpczpkaWZmZXJlbnQgcHJlc2lkZW50cworIHktYXhpczp0aGUgd2VpZ2h0IG9mIGEgY2VydGFpbiBraW5kIG9mIHBlcnNvbmFsIHByb25vdW4gYmVpbmcgdXNlZC4KCmBgYHtyfQplQmFyKG5ldzQsIH5uYW1lLCB+cHJvcG9ydGlvbiwgfnR5cGUpCmBgYAoKPGg0PjQuNSBFYWNoIHBlcnNvbmFsIHByb25vdW4ncyAiRmFuIENsdWIiIGZlYXR1cmUgOiBwb3NpdGl2ZT8gbmVnYXRpdmU/IDwvaDQ+CgpgYGB7cix3YXJuaW5nPUZ9CmRhdGEocG9zaXRpdmUud29yZHMpCmRhdGEobmVnYXRpdmUud29yZHMpCnNlbnRpbWVudF9hbmFseTwtZnVuY3Rpb24od29yZHMpCnsKICAgICAgc2NvcmU8LU5VTEwKICAgICAgIyBjb21wYXJlIHdvcmRzIHRvIHRoZSBkaWN0aW9uYXJpZXMgb2YgcG9zaXRpdmUgJiBuZWdhdGl2ZSB0ZXJtcwogICAgICBwb3NpdGl2ZS5tYXRjaGVzID0gbWF0Y2god29yZHMsIHBvc2l0aXZlLndvcmRzKQogICAgICBuZWdhdGl2ZS5tYXRjaGVzID0gbWF0Y2god29yZHMsIG5lZ2F0aXZlLndvcmRzKQogICAgICAjIGdldCB0aGUgcG9zaXRpb24gb2YgdGhlIG1hdGNoZWQgdGVybSBvciBOQQogICAgICAjIHdlIGp1c3Qgd2FudCBhIFRSVUUvRkFMU0UKICAgICAgcG9zaXRpdmVfbWF0Y2hlcyA9ICFpcy5uYShwb3NpdGl2ZS5tYXRjaGVzKQogICAgICBuZWdhdGl2ZV9tYXRjaGVzID0gIWlzLm5hKG5lZ2F0aXZlLm1hdGNoZXMpCiAgICAgIHNjb3JlID0gc3VtKHBvc2l0aXZlX21hdGNoZXMpIC0gc3VtKG5lZ2F0aXZlX21hdGNoZXMpIAogICAgICByZXR1cm4oc2NvcmUpCn0Kc2VudGlfdmVjPC1OVUxMCmZvcihpIGluIHNlcShucm93KGluYXVnLmxpc3QpKSkgewogIHRlc3Q8LW1hdHNvcnRbbWF0c29ydFssIm5hbWUiXT09cGFzdGUoaW5hdWcubGlzdCRGaWxlW2ldLGluYXVnLmxpc3QkVGVybVtpXSksIndvcmQiXQogIHNlbnRpX3ZlY1tpXTwtc2VudGltZW50X2FuYWx5KHRlc3QpCn0Kc3ZuYW1lPC1OVUxMCmZvcihpIGluIHNlcShucm93KGluYXVnLmxpc3QpKSkgewpzdm5hbWVbaV0gPC0gcGFzdGUoaW5hdWcubGlzdCRGaWxlW2ldLCBpbmF1Zy5saXN0JFRlcm1baV0pIH0KCiNzZW50aW1lbnQgdnMgcGVyc29uCnNlbnRpX21hdDwtY2JpbmQocHBuYW1lLHNlbnRpX3ZlYykKbjE8LW1hdGNoKHJvd25hbWVzKGRhdGExKSxwcG5hbWUpCm4yPC1tYXRjaChyb3duYW1lcyhkYXRhMikscHBuYW1lKQpuMzwtbWF0Y2gocm93bmFtZXMoZGF0YTMpLHBwbmFtZSkKbjQ8LW1hdGNoKHJvd25hbWVzKGRhdGE0KSxwcG5hbWUpCnNlbnRpX21hdDI8LWNiaW5kKHNlbnRpX21hdFtuMSwyXSxyZXAoImZpcnN0MSIsMTApKQpzZW50aV9tYXQyPC1yYmluZCggc2VudGlfbWF0MiAsIGNiaW5kKHNlbnRpX21hdFtuMiwyXSxyZXAoImZpcnN0MiIsMTApKSApCnNlbnRpX21hdDI8LXJiaW5kKCBzZW50aV9tYXQyICwgY2JpbmQoc2VudGlfbWF0W24zLDJdLHJlcCgic2Vjb25kIiwxMCkpICkKc2VudGlfbWF0MjwtcmJpbmQoIHNlbnRpX21hdDIgLCBjYmluZChzZW50aV9tYXRbbjQsMl0scmVwKCJ0aGlyZCIsMTApKSApCmNvbG5hbWVzKHNlbnRpX21hdDIpPC1jKCJzZW50aW1lbnRhbF9zY29yZXMiLCJwZXJzb25hbF9wcm9uIikKZGF0PC1kYXRhLmZyYW1lKHNlbnRpX21hdDIpCnAgPC0gZ2dwbG90KGRhdCwgYWVzKHBlcnNvbmFsX3Byb24sIGFzLm51bWVyaWMoc2VudGltZW50YWxfc2NvcmVzKSkpCnAgKyBnZW9tX2JveHBsb3QoKQpgYGAKCjxwPkFjY29yZGluZyB0byB0aGUgcGxvdCwgRmlyc3QgcGVyc29uIHBsdXJhbCdzICJGYW4gQ2x1YiIgdGVuZCB0byBiZSBtb3JlIG5lZ2F0aXZlLHdoaWxlIHRoZSB0aGlyZCBwZXJzb24gZm9ybSdzICJGYW4gQ2x1YiIgc2VlbSB0byBiZSBtb3JlIHBvc2l0aXZlLiBCdXQgdGhlcmUgaXMgbm8gb2J2aW91cyBkaWZmZXJlbmNlcy48L3A+Cgo8aDQ+NC42IEVhY2ggcGVyc29uYWwgcHJvbm91bidzICJGYW4gQ2x1YiIgZmVhdHVyZSA6IGF2ZXJhZ2Ugb2Ygd29yZCB1c2luZyB0aW1lcz8gPC9oND4KYGBge3Isd2FybmluZz1GfQojYXZnIHRpbWUgdnMgcGVyc29uCmF2Z19tYXQ8LW1hdHJpeChucm93ID0gbnJvdyhpbmF1Zy5saXN0KSxuY29sID0gMikKYXZnX21hdFssMV08LXBwbmFtZQpmb3IoaSBpbiBzZXEobnJvdyhpbmF1Zy5saXN0KSkpIHsKICB0ZXN0PC1tYXRzb3J0W21hdHNvcnRbLCJuYW1lIl09PXBhc3RlKGluYXVnLmxpc3QkRmlsZVtpXSxpbmF1Zy5saXN0JFRlcm1baV0pLF0KICBhdmdfbWF0W2ksMl08LXN1bShhcy5udW1lcmljKHRlc3RbLDNdKSkvbnJvdyh0ZXN0KQp9CnNlbnRpX21hdDM8LWNiaW5kKGF2Z19tYXRbbjEsMl0scmVwKCJmaXJzdDEiLDEwKSkKc2VudGlfbWF0MzwtcmJpbmQoIHNlbnRpX21hdDMgLCBjYmluZChhdmdfbWF0W24yLDJdLHJlcCgiZmlyc3QyIiwxMCkpICkKc2VudGlfbWF0MzwtcmJpbmQoIHNlbnRpX21hdDMgLCBjYmluZChhdmdfbWF0W24zLDJdLHJlcCgic2Vjb25kIiwxMCkpICkKc2VudGlfbWF0MzwtcmJpbmQoIHNlbnRpX21hdDMgLCBjYmluZChhdmdfbWF0W240LDJdLHJlcCgidGhpcmQiLDEwKSkgKQpjb2xuYW1lcyhzZW50aV9tYXQzKTwtYygid29yZF9hdmdfdGltZSIsInBlcnNvbmFsX3Byb24iKQpkYXQ8LWRhdGEuZnJhbWUoc2VudGlfbWF0MykKcCA8LSBnZ3Bsb3QoZGF0LCBhZXMocGVyc29uYWxfcHJvbiwgYXMubnVtZXJpYyh3b3JkX2F2Z190aW1lKSkpCnAgKyBnZW9tX2JveHBsb3QoKQpgYGAKPHA+QWNjb3JkaW5nIHRvIHRoZSBwbG90LCBGaXJzdCBwZXJzb24gcGx1cmFsJ3MgIkZhbiBDbHViIiB0ZW5kIHRvIHVzZSB0aGUgc2FtZSB3b3JkcyBmb3IgbGVzcyB0aW1lcyx0aGUgbWVkaWFuIGlzIGFib3V0IDEyIHRpbWVzO3doaWxlIHRoZSB0aGlyZCBwZXJzb24gZm9ybSdzICJGYW4gQ2x1YiIgdXNpbmcgdGhlIHNhbWUgd29yZHMgZm9yIG1vcmUgdGltZXMsdGhlIG1lZGlhbiBpcyBhYm91dCAyNyB0aW1lcy4gPC9wPgoKPGgzPjxmb250IGZhY2U9IlRpbWVzIE5ldyBSb21hbiI+UGFydCA1IC0gV2hhdCBhcmUgdGhleSB0YWxraW5nL2ZlZWxpbmcgdXNpbmcgcGVyc29uYWwgcHJvbm91biA/IDwvZm9udD48L2gzPgoKPHA+SW4gdGhpcyBwYXJ0LHdlIGdvIGEgbGl0dGxlIGRlZXBlciB0byBlYWNoIHNlbnRlbmNlcy5XaGF0J3MgdGhlIHdlaWdodCBvZiBwZXJzb25hbCBwcm9ub3VucyB1c2VkIGluIGVhY2ggc2VudGVuY2VzPyBJbiB0aG9zZSBzZW50ZW5jZXMsd2hhdCBhcmUgdGhleSB0YWxraW5nIGFib3V0IGFuZCB3aGF0IGVtb3Rpb24gYXJlIHRoZXkgdHJ5IHRvIGNvbnZleSx0aGVzZSBhcmUgd2hhdCB3ZSBjYXJlIGluIHRoaXMgcGFydC4KPHA+V2UgbWFpbmx5IG1ha2UgdHdvIHBsb3RzIHRvIGNvbXBhcmUuT25lIG9mIHRoZW0gaXMgc3RhY2tlZCBiYXIgcGxvdCxkZW1vbnN0cmF0aW5nIHRoZSBmb3VyIHByb3BvcnRpb25zIG9mIGZvdXIgcGVyc29uYWwgcHJvbm91bnMgZm9yIGVhY2ggc2VudGVuY2UgaW4gb25lIHNwZWVjaC5UaGUgc2Vjb25kIGlzIGFuIGFyZWEgcGxvdCxzaG93aW5nIGRpZmZlcmVudCBlbW90aW9ucyBmb3IgZWFjaCBzZW50ZW5jZSBpbiBvbmUgc3BlZWNoLjwvcD4KPHA+QWZ0ZXIgY2hlY2sgdGhlIHBsb3RzIGZvciBlYWNoIHByZXNpZGVudHMgb25lIGJ5IG9uZSxJIHdpbGwgc2hhcmUgdGhyZWUgZmluZGluZ3MgaGVyZS48L3A+Cgo8aDQ+PGZvbnQgZmFjZT0iVGltZXMgTmV3IFJvbWFuIj5GaW5kaW5nIDE6Zmlyc3Qgc2luZ3VsYXIgZm9ybSBhbHdheXMgY29tZSB3aXRoIHRydXN0IGFuZCBhbnRpY2lwYXRpb24uIDwvZm9udD48L2g0PgoKKyBHZW9yZ2UgV2FzaGluZ3RvbjogVGhlcmUgYXJlIDQgc2VudGVuY2VzIGluIGhpcyBzcGVlY2hlcyx3aXRoIDEsMiBhbmQgNCB1c2luZyBoaWdoIGZyZXF1ZW5jeSBvZiBmaXJzdCBwZXJzb24gc2luZ3VsYXIgcHJvbm91bixhbmQgdGhlIGVtb3Rpb25zIG9mIHRoZXNlIHNlbnRlbmNlcyBhcmUgbWFpbmx5IHRydXN0LgoKCmBgYHtyLHdhcm5pbmc9Rn0Kc2VudGVuX21hdDI8LW1lbHQoc2VudGVuX21hdCgyKSkKc2VuX2RhdDwtZGF0YS5mcmFtZShzZW50ZW5jZS5udW1iZXI9c2VudGVuX21hdDIkVmFyMSx0aW1lcz1zZW50ZW5fbWF0MiR2YWx1ZSxwZXJzb25hbF9wcm9ub3VuPXNlbnRlbl9tYXQyJFZhcjIsMikKc2VudGlfbWF0PC1yb3VuZChjb3VudF9lbW8oMilbLGMoMSwyLDQsNSw3LDgpXSwyKQpyb3duYW1lcyhzZW50aV9tYXQpPC1zZXEoMSxucm93KHNlbnRpX21hdCkpCnNlbnRpX21hdDI8LW1lbHQoc2VudGlfbWF0KQpzZW50aV9kYXQ8LWRhdGEuZnJhbWUoc2VudGVuY2VfbnVtYmVyPXNlbnRpX21hdDIkVmFyMSxzY29yZT1zZW50aV9tYXQyJHZhbHVlLHNlbnRpbWVudD1zZW50aV9tYXQyJFZhcjIpCgojcGFyKG1mcm93PWMoMSwyKSkKYTE8LWdncGxvdChzZW5fZGF0LGFlcyhzZW50ZW5jZS5udW1iZXIsdGltZXMsZmlsbD1wZXJzb25hbF9wcm9ub3VuKSkrZ2VvbV9iYXIoc3RhdD0iaWRlbnRpdHkiLHBvc2l0aW9uPSJzdGFjayIpK2dndGl0bGUoIiIpK2d1aWRlcyhmaWxsPWd1aWRlX2xlZ2VuZCh0aXRsZT1OVUxMKSkrIHNjYWxlX2ZpbGxfYnJld2VyKHBhbGV0dGUgPSAiQmx1ZXMiKSsgeGxhYigic2VudGVuY2UgbnVtYmVyIikKI2IxPC1nZ3Bsb3Qoc2VudGlfZGF0LCBhZXMoeCA9IHNlbnRlbmNlX251bWJlciwgeSA9IHNjb3JlLCBmaWxsID0gc2VudGltZW50KSkgKwojICBnZW9tX2FyZWEoKSAKIyArIHNjYWxlX2ZpbGxfYnJld2VyKHBhbGV0dGUgPSAiUmRCdSIsIGJyZWFrcyA9IHJldihjKGZhY3RvcihzZW50aW1lbnQpKSkpCiNiMTwtZ2dwbG90KHNlbnRpX2RhdCxhZXMoeCA9IHNlbnRlbmNlX251bWJlciwgeSA9IHNjb3JlLCBmaWxsID0gc2VudGltZW50KSkrZ2VvbV9iYXIoc3RhdD0iaWRlbnRpdHkiLHBvc2l0aW9uPSJzdGFjayIpK2dndGl0bGUoIiIpK2d1aWRlcyhmaWxsPWd1aWRlX2xlZ2VuZCh0aXRsZT1OVUxMKSkKI2dyaWQuYXJyYW5nZShhMSxiMSxucm93PTIpCmExCmBgYAoKCmBgYHtyfQplQXJlYShzZW50aV9tYXQpCiNmaW5kIHRvcGljcwojdGVzdDwtdG9waWNfd2MoMiwxKQojdGVzdDwtdGVzdFs3OjY1LF0KI2RhdDwtZGF0YS5mcmFtZSh3b3JkPXRlc3RbLCJ3b3JkIl0sZnJlcT10ZXN0WywibiJdKQojZVdvcmRjbG91ZChkYXQsIG5hbWV2YXIgPSB+d29yZCwgZGF0YXZhciA9IH5mcmVxLHNpemUgPSBjKDYwMCwgNjAwKSx0aXRsZSA9ICJHZW9yZ2UgV2FzaGluZ3RvbiAmIGZpc3QgcGVyc29uIHNpbmd1bGFyIixyb3RhdGlvblJhbmdlID0gYygtMSwgMSkpCmBgYApbZm9yIHRoZSBhcmVhIHBsb3RdCgp4LWF4aXM6c2VudGVuY2UgbnVtYmVyCgp5LWF4aXM6dGhlIHdlaWdodCBvZiBhIGNlcnRhaW4ga2luZCBvZiBlbW90aW9uIGJlaW5nIGRldGVjdGVkLgoKKyBXaWxsaWFtIE1jS2lubGV5OiBUaGUgc2VudGVuY2VzIHVzaW5nIGZpcnN0IHBlcnNvbiBzaW5ndWxhciBwcm9ub3VuIGZyZXF1ZW50bHkgYWxzbyBjb250YWlucyB0cnVzdCBlbW90aW9uLgoKCmBgYHtyfQpzZW50ZW5fbWF0MjwtbWVsdChzZW50ZW5fbWF0KDI4KSkKc2VuX2RhdDwtZGF0YS5mcmFtZShzZW50ZW5jZS5udW1iZXI9c2VudGVuX21hdDIkVmFyMSx0aW1lcz1zZW50ZW5fbWF0MiR2YWx1ZSxwZXJzb25hbF9wcm9ub3VuPXNlbnRlbl9tYXQyJFZhcjIsMikKc2VudGlfbWF0PC1yb3VuZChjb3VudF9lbW8oMjgpWyxjKDEsMiw0LDUsNyw4KV0sMikKcm93bmFtZXMoc2VudGlfbWF0KTwtc2VxKDEsbnJvdyhzZW50aV9tYXQpKQpzZW50aV9tYXQyPC1tZWx0KHNlbnRpX21hdCkKc2VudGlfZGF0PC1kYXRhLmZyYW1lKHNlbnRlbmNlX251bWJlcj1zZW50aV9tYXQyJFZhcjEsc2NvcmU9c2VudGlfbWF0MiR2YWx1ZSxzZW50aW1lbnQ9c2VudGlfbWF0MiRWYXIyKQoKI3BhcihtZnJvdz1jKDEsMikpCmExPC1nZ3Bsb3Qoc2VuX2RhdCxhZXMoc2VudGVuY2UubnVtYmVyLHRpbWVzLGZpbGw9cGVyc29uYWxfcHJvbm91bikpK2dlb21fYmFyKHN0YXQ9ImlkZW50aXR5Iixwb3NpdGlvbj0ic3RhY2siKStnZ3RpdGxlKCIiKStndWlkZXMoZmlsbD1ndWlkZV9sZWdlbmQodGl0bGU9TlVMTCkpKyBzY2FsZV9maWxsX2JyZXdlcihwYWxldHRlID0gIkJsdWVzIikrIHhsYWIoInNlbnRlbmNlIG51bWJlciIpCiNiMTwtZ2dwbG90KHNlbnRpX2RhdCwgYWVzKHggPSBzZW50ZW5jZV9udW1iZXIsIHkgPSBzY29yZSwgZmlsbCA9IHNlbnRpbWVudCkpICsKIyAgZ2VvbV9hcmVhKCkgCiMgKyBzY2FsZV9maWxsX2JyZXdlcihwYWxldHRlID0gIlJkQnUiLCBicmVha3MgPSByZXYoYyhmYWN0b3Ioc2VudGltZW50KSkpKQojYjE8LWdncGxvdChzZW50aV9kYXQsYWVzKHggPSBzZW50ZW5jZV9udW1iZXIsIHkgPSBzY29yZSwgZmlsbCA9IHNlbnRpbWVudCkpK2dlb21fYmFyKHN0YXQ9ImlkZW50aXR5Iixwb3NpdGlvbj0ic3RhY2siKStnZ3RpdGxlKCIiKStndWlkZXMoZmlsbD1ndWlkZV9sZWdlbmQodGl0bGU9TlVMTCkpCiNncmlkLmFycmFuZ2UoYTEsYjEsbnJvdz0yKQphMQplQXJlYShzZW50aV9tYXQpCgojZmluZF9zZW4oMjgsMTM0KQojZmluZF9zZW4oMjgsMTM1KQojZmluZF9zZW4oMjgsMTM2KQojZmluZF9zZW4oMjgsMTM3KQojdGVzdDwtdG9waWNfd2MoMjgsMSlbMTo2MCxdCiN0ZXN0PC10ZXN0WzY6NjAsXQojZGF0PC1kYXRhLmZyYW1lKHdvcmQ9dGVzdFssIndvcmQiXSxmcmVxPXRlc3RbLCJuIl0pCiNlV29yZGNsb3VkKGRhdCwgbmFtZXZhciA9IH53b3JkLCBkYXRhdmFyID0gfmZyZXEsc2l6ZSA9IGMoNjAwLCA2MDApLHRpdGxlID0gIldpbGxpYW1NY0tpbmxleSAmIGZpc3QgcGVyc29uIHNpbmd1bGFyIixyb3RhdGlvblJhbmdlID0gYygtMSwgMSkpCmBgYAo8aDQ+PGZvbnQgZmFjZT0iVGltZXMgTmV3IFJvbWFuIj5GaW5kaW5nIDIgOmZpcnN0IHBsdXJhbCBmb3JtIGFsd2F5cyBjb252ZXkgcG9zaXRpdmUgZW1vdGlvbnMuPC9mb250PjwvaDQ+CgorIFJpY2hhcmQgTml4b24KCmBgYHtyLHdhcm5pbmc9Rn0Kc2VudGVuX21hdDI8LW1lbHQoc2VudGVuX21hdCg0NSkpCnNlbl9kYXQ8LWRhdGEuZnJhbWUoc2VudGVuY2UubnVtYmVyPXNlbnRlbl9tYXQyJFZhcjEsdGltZXM9c2VudGVuX21hdDIkdmFsdWUscGVyc29uYWxfcHJvbm91bj1zZW50ZW5fbWF0MiRWYXIyKQoKcGFyKG1mcm93PWMoNCwxKSwgbWFyPWMoMSwwLDIsMCksIGJ0eT0ibiIsIHhheHQ9Im4iLCB5YXh0PSJuIiwgZm9udC5tYWluPTEpCmEyPC1nZ3Bsb3Qoc2VuX2RhdCxhZXMoc2VudGVuY2UubnVtYmVyLHRpbWVzLGZpbGw9cGVyc29uYWxfcHJvbm91bikpK2dlb21fYmFyKHN0YXQ9ImlkZW50aXR5Iixwb3NpdGlvbj0ic3RhY2siKStnZ3RpdGxlKCIiKStndWlkZXMoZmlsbD1ndWlkZV9sZWdlbmQodGl0bGU9TlVMTCkpKwogIHNjYWxlX2ZpbGxfYnJld2VyKHBhbGV0dGUgPSAiQmx1ZXMiKSsgeGxhYigic2VudGVuY2UgbnVtYmVyIikKCnNlbnRpX21hdDM8LXJvdW5kKGNvdW50X2Vtbyg0NSlbLGMoMSwyLDQsNSw3LDgpXSwyKQpyb3duYW1lcyhzZW50aV9tYXQzKTwtc2VxKDEsbnJvdyhzZW50aV9tYXQzKSkKc2VudGlfbWF0NDwtbWVsdChzZW50aV9tYXQzKQpzZW50aV9kYXQyPC1kYXRhLmZyYW1lKHNlbnRlbmNlX251bWJlcj1zZW50aV9tYXQ0JFZhcjEsc2NvcmU9c2VudGlfbWF0NCR2YWx1ZSxzZW50aW1lbnQ9c2VudGlfbWF0NCRWYXIyKQojYjI8LWdncGxvdChzZW50aV9kYXQyLCBhZXMoeCA9IHNlbnRlbmNlX251bWJlciwgeSA9IHNjb3JlLCBmaWxsID0gc2VudGltZW50KSkgKwojICBnZW9tX2FyZWEoKSAKI2IyPC1nZ3Bsb3Qoc2VudGlfZGF0MixhZXMoeCA9IHNlbnRlbmNlX251bWJlciwgeSA9IHNjb3JlLCBmaWxsID0gc2VudGltZW50KSkrZ2VvbV9iYXIoc3RhdD0iaWRlbnRpdHkiLHBvc2l0aW9uPSJzdGFjayIpK2dndGl0bGUoIiIpK2d1aWRlcyhmaWxsPWd1aWRlX2xlZ2VuZCh0aXRsZT1OVUxMKSkKYTIKCmBgYAoKYGBge3J9CmFwcGx5KHNlbnRpX21hdDMsMixtZWFuKQplQXJlYShzZW50aV9tYXQzKQojdGVzdDwtdG9waWNfd2MoNDUsMilbMTo2MCxdCiNkYXQ8LWRhdGEuZnJhbWUod29yZD10ZXN0Wywid29yZCJdLGZyZXE9dGVzdFssIm4iXSkKI2VXb3JkY2xvdWQoZGF0LCBuYW1ldmFyID0gfndvcmQsIGRhdGF2YXIgPSB+ZnJlcSkKYGBgCgpbZm9yIHRoZSBhcmVhIHBsb3RdCgp4LWF4aXM6c2VudGVuY2UgbnVtYmVyCgp5LWF4aXM6dGhlIHdlaWdodCBvZiBhIGNlcnRhaW4ga2luZCBvZiBlbW90aW9uIGJlaW5nIGRldGVjdGVkLgoKKyBCYXJhY2sgT2JhbWEKCmBgYHtyfQpzZW50ZW5fbWF0MjwtbWVsdChzZW50ZW5fbWF0KDU3KSkKc2VuX2RhdDwtZGF0YS5mcmFtZShzZW50ZW5jZS5udW1iZXI9c2VudGVuX21hdDIkVmFyMSx0aW1lcz1zZW50ZW5fbWF0MiR2YWx1ZSxwZXJzb25hbF9wcm9ub3VuPXNlbnRlbl9tYXQyJFZhcjIsMikKc2VudGlfbWF0PC1yb3VuZChjb3VudF9lbW8oNTcpWyxjKDEsMiw0LDUsNyw4KV0sMikKcm93bmFtZXMoc2VudGlfbWF0KTwtc2VxKDEsbnJvdyhzZW50aV9tYXQpKQpzZW50aV9tYXQyPC1tZWx0KHNlbnRpX21hdCkKc2VudGlfZGF0PC1kYXRhLmZyYW1lKHNlbnRlbmNlX251bWJlcj1zZW50aV9tYXQyJFZhcjEsc2NvcmU9c2VudGlfbWF0MiR2YWx1ZSxzZW50aW1lbnQ9c2VudGlfbWF0MiRWYXIyKQoKI3BhcihtZnJvdz1jKDEsMikpCmExPC1nZ3Bsb3Qoc2VuX2RhdCxhZXMoc2VudGVuY2UubnVtYmVyLHRpbWVzLGZpbGw9cGVyc29uYWxfcHJvbm91bikpK2dlb21fYmFyKHN0YXQ9ImlkZW50aXR5Iixwb3NpdGlvbj0ic3RhY2siKStnZ3RpdGxlKCIiKStndWlkZXMoZmlsbD1ndWlkZV9sZWdlbmQodGl0bGU9TlVMTCkpKyBzY2FsZV9maWxsX2JyZXdlcihwYWxldHRlID0gIkJsdWVzIikrIHhsYWIoInNlbnRlbmNlIG51bWJlciIpCiNiMTwtZ2dwbG90KHNlbnRpX2RhdCwgYWVzKHggPSBzZW50ZW5jZV9udW1iZXIsIHkgPSBzY29yZSwgZmlsbCA9IHNlbnRpbWVudCkpICsKIyAgZ2VvbV9hcmVhKCkgCiMgKyBzY2FsZV9maWxsX2JyZXdlcihwYWxldHRlID0gIlJkQnUiLCBicmVha3MgPSByZXYoYyhmYWN0b3Ioc2VudGltZW50KSkpKQojYjE8LWdncGxvdChzZW50aV9kYXQsYWVzKHggPSBzZW50ZW5jZV9udW1iZXIsIHkgPSBzY29yZSwgZmlsbCA9IHNlbnRpbWVudCkpK2dlb21fYmFyKHN0YXQ9ImlkZW50aXR5Iixwb3NpdGlvbj0ic3RhY2siKStnZ3RpdGxlKCIiKStndWlkZXMoZmlsbD1ndWlkZV9sZWdlbmQodGl0bGU9TlVMTCkpCiNncmlkLmFycmFuZ2UoYTEsYjEsbnJvdz0yKQphMQplQXJlYShzZW50aV9tYXQpCiNmaW5kX3NlbigyOCwxMzQpCiNmaW5kX3NlbigyOCwxMzUpCiNmaW5kX3NlbigyOCwxMzYpCiNmaW5kX3NlbigyOCwxMzcpCmFwcGx5KHNlbnRpX21hdCwyLG1lYW4pCiN0ZXN0PC10b3BpY193YygzNSwyKVsxOjYwLF0KI2RhdDwtZGF0YS5mcmFtZSh3b3JkPXRlc3RbLCJ3b3JkIl0sZnJlcT10ZXN0WywibiJdKQojZVdvcmRjbG91ZChkYXQsIG5hbWV2YXIgPSB+d29yZCwgZGF0YXZhciA9IH5mcmVxKQpgYGAKCjxoND48Zm9udCBmYWNlPSJUaW1lcyBOZXcgUm9tYW4iPkZpbmRpbmcgMyA6IEFuZ2VyIG9mdGVuIGJlZ2luIHdpdGggdGhpcmQgcGVyc29uIGZvcm0uPC9mb250PjwvaDQ+CgorIFVseXNzZXMgUy5HcmFudAoKCmBgYHtyfQpzZW50ZW5fbWF0MjwtbWVsdChzZW50ZW5fbWF0KDIxKSkKc2VuX2RhdDwtZGF0YS5mcmFtZShzZW50ZW5jZS5udW1iZXI9c2VudGVuX21hdDIkVmFyMSx0aW1lcz1zZW50ZW5fbWF0MiR2YWx1ZSxwZXJzb25hbF9wcm9ub3VuPXNlbnRlbl9tYXQyJFZhcjIpCmEzPC1nZ3Bsb3Qoc2VuX2RhdCxhZXMoc2VudGVuY2UubnVtYmVyLHRpbWVzLGZpbGw9cGVyc29uYWxfcHJvbm91bikpK2dlb21fYmFyKHN0YXQ9ImlkZW50aXR5Iixwb3NpdGlvbj0ic3RhY2siKStnZ3RpdGxlKCIiKStndWlkZXMoZmlsbD1ndWlkZV9sZWdlbmQodGl0bGU9TlVMTCkpKyBzY2FsZV9maWxsX2JyZXdlcihwYWxldHRlID0gIkJsdWVzIikrIHhsYWIoInNlbnRlbmNlIG51bWJlciIpCnNlbnRpX21hdDU8LXJvdW5kKGNvdW50X2VtbygyMSlbLGMoMSwyLDQsNSw3LDgpXSwyKQpyb3duYW1lcyhzZW50aV9tYXQ1KTwtc2VxKDEsbnJvdyhzZW50aV9tYXQ1KSkKc2VudGlfbWF0NjwtbWVsdChzZW50aV9tYXQ1KQpzZW50aV9kYXQzPC1kYXRhLmZyYW1lKHNlbnRlbmNlX251bWJlcj1zZW50aV9tYXQ2JFZhcjEsc2NvcmU9c2VudGlfbWF0NiR2YWx1ZSxzZW50aW1lbnQ9c2VudGlfbWF0NiRWYXIyKQpiMzwtZ2dwbG90KHNlbnRpX2RhdDMsYWVzKHggPSBzZW50ZW5jZV9udW1iZXIsIHkgPSBzY29yZSwgZmlsbCA9IHNlbnRpbWVudCkpK2dlb21fYmFyKHN0YXQ9ImlkZW50aXR5Iixwb3NpdGlvbj0ic3RhY2siKStnZ3RpdGxlKCIiKStndWlkZXMoZmlsbD1ndWlkZV9sZWdlbmQodGl0bGU9TlVMTCkpCiNiMzwtZ2dwbG90KHNlbnRpX2RhdDMsIGFlcyh4ID0gc2VudGVuY2VfbnVtYmVyLCB5ID0gc2NvcmUsIGZpbGwgPSBzZW50aW1lbnQpKSArCiMgIGdlb21fYXJlYSgpIAphMwpgYGAKCgpgYGB7cn0KZUFyZWEoc2VudGlfbWF0NSkKYXBwbHkoc2VudGlfbWF0NSwyLG1lYW4sbmEucm09VCkKI3Rlc3Q8LXRvcGljX3djKDU3LDIpWzE6NjAsXQojZGF0PC1kYXRhLmZyYW1lKHdvcmQ9dGVzdFssIndvcmQiXSxmcmVxPXRlc3RbLCJuIl0pCiNlV29yZGNsb3VkKGRhdCwgbmFtZXZhciA9IH53b3JkLCBkYXRhdmFyID0gfmZyZXEpCmBgYApbZm9yIHRoZSBhcmVhIHBsb3RdCgp4LWF4aXM6c2VudGVuY2UgbnVtYmVyCgp5LWF4aXM6dGhlIHdlaWdodCBvZiBhIGNlcnRhaW4ga2luZCBvZiBlbW90aW9uIGJlaW5nIGRldGVjdGVkLgoKCisgRHdpZ2h0IEQuRWlzZW5ob3dlcgpgYGB7cn0Kc2VudGVuX21hdDI8LW1lbHQoc2VudGVuX21hdCg0MykpCnNlbl9kYXQ8LWRhdGEuZnJhbWUoc2VudGVuY2UubnVtYmVyPXNlbnRlbl9tYXQyJFZhcjEsdGltZXM9c2VudGVuX21hdDIkdmFsdWUscGVyc29uYWxfcHJvbm91bj1zZW50ZW5fbWF0MiRWYXIyKQphMzwtZ2dwbG90KHNlbl9kYXQsYWVzKHNlbnRlbmNlLm51bWJlcix0aW1lcyxmaWxsPXBlcnNvbmFsX3Byb25vdW4pKStnZW9tX2JhcihzdGF0PSJpZGVudGl0eSIscG9zaXRpb249InN0YWNrIikrZ2d0aXRsZSgiIikrZ3VpZGVzKGZpbGw9Z3VpZGVfbGVnZW5kKHRpdGxlPU5VTEwpKSsgc2NhbGVfZmlsbF9icmV3ZXIocGFsZXR0ZSA9ICJCbHVlcyIpKyB4bGFiKCJzZW50ZW5jZSBudW1iZXIiKQpzZW50aV9tYXQ1PC1yb3VuZChjb3VudF9lbW8oNDMpWyxjKDEsMiw0LDUsNyw4KV0sMikKcm93bmFtZXMoc2VudGlfbWF0NSk8LXNlcSgxLG5yb3coc2VudGlfbWF0NSkpCnNlbnRpX21hdDY8LW1lbHQoc2VudGlfbWF0NSkKc2VudGlfZGF0MzwtZGF0YS5mcmFtZShzZW50ZW5jZV9udW1iZXI9c2VudGlfbWF0NiRWYXIxLHNjb3JlPXNlbnRpX21hdDYkdmFsdWUsc2VudGltZW50PXNlbnRpX21hdDYkVmFyMikKYjM8LWdncGxvdChzZW50aV9kYXQzLGFlcyh4ID0gc2VudGVuY2VfbnVtYmVyLCB5ID0gc2NvcmUsIGZpbGwgPSBzZW50aW1lbnQpKStnZW9tX2JhcihzdGF0PSJpZGVudGl0eSIscG9zaXRpb249InN0YWNrIikrZ2d0aXRsZSgiIikrZ3VpZGVzKGZpbGw9Z3VpZGVfbGVnZW5kKHRpdGxlPU5VTEwpKQojYjM8LWdncGxvdChzZW50aV9kYXQzLCBhZXMoeCA9IHNlbnRlbmNlX251bWJlciwgeSA9IHNjb3JlLCBmaWxsID0gc2VudGltZW50KSkgKwojICBnZW9tX2FyZWEoKSAKYTMKZUFyZWEoc2VudGlfbWF0NSkKYXBwbHkoc2VudGlfbWF0NSwyLG1lYW4sbmEucm09VCkKI3Rlc3Q8LXRvcGljX3djKDU3LDIpWzE6NjAsXQojZGF0PC1kYXRhLmZyYW1lKHdvcmQ9dGVzdFssIndvcmQiXSxmcmVxPXRlc3RbLCJuIl0pCiNlV29yZGNsb3VkKGRhdCwgbmFtZXZhciA9IH53b3JkLCBkYXRhdmFyID0gfmZyZXEpCmBgYAoKCjxoMz48Zm9udCBmYWNlPSJUaW1lcyBOZXcgUm9tYW4iPlBhcnQgNiAtIE5leHQgc3RlcDwvZm9udD48L2gzPgoKKyA8aDQ+Q29sbGVjdCBtb3JlIGRhdGEgZm9yIG90aGVyIGZvcm1hbCBzcGVlY2hlcyB0byBnYWluIG1vcmUgY29udmluY2luZyBhbmFseXNpcy48aDQ+CisgPGg0PlNtb290aCB0aGUgZW1vdGlvbiBmdW5jdGlvbiB0byBtYWtlIGl0IG1vcmUgY2xlYXIuPDQ+CgoK